Selectively replace multiple instances of a character within a string: Difference between revisions
m (→{{header|J}}: get left and right right) |
(Added Vlang) |
||
Line 211:
<pre>abracadabra -> AErBcadCbFD
caarabadrab -> cABraECdFDb</pre>
=={{header|Vlang}}==
A similar approach to the C++ entry.
<lang ruby>fn selectively_replace_chars(s string, char_map map[string]string) string {
mut bytes := s.bytes()
mut counts := {
'a': 0
'b': 0
'r': 0
}
for i := s.len - 1; i >= 0; i-- {
c := s[i].ascii_str()
if c in ['a', 'b', 'r'] {
bytes[i] = char_map[c][counts[c]]
counts[c]++
}
}
return bytes.bytestr()
}
fn main() {
char_map := {
'a': 'DCaBA'
'b': 'bE'
'r': 'Fr'
}
for old in ['abracadabra', 'caaarrbabad'] {
new := selectively_replace_chars(old, char_map)
println('$old -> $new')
}
}</lang>
{{out}}
<pre>
abracadabra -> AErBcadCbFD
caaarrbabad -> cABarFECbDd
</pre>
=={{header|Wren}}==
|
Revision as of 11:25, 3 June 2022
- Task
This is admittedly a trivial task but I thought it would be interesting to see how succinctly (or otherwise) different languages can handle it.
Given the string: "abracadabra", replace programatically:
- the first 'a' with 'A'
- the second 'a' with 'B'
- the fourth 'a' with 'C'
- the fifth 'a' with 'D'
- the first 'b' with 'E'
- the second 'r' with 'F'
Note that there is no replacement for the third 'a', second 'b' or first 'r'.
The answer should, of course, be : "AErBcadCbFD".
- Metrics
- Counting
- Word frequency
- Letter frequency
- Jewels and stones
- I before E except after C
- Bioinformatics/base count
- Count occurrences of a substring
- Count how many vowels and consonants occur in a string
- Remove/replace
- XXXX redacted
- Conjugate a Latin verb
- Remove vowels from a string
- String interpolation (included)
- Strip block comments
- Strip comments from a string
- Strip a set of characters from a string
- Strip whitespace from a string -- top and tail
- Strip control codes and extended characters from a string
- Anagrams/Derangements/shuffling
- Word wheel
- ABC problem
- Sattolo cycle
- Knuth shuffle
- Ordered words
- Superpermutation minimisation
- Textonyms (using a phone text pad)
- Anagrams
- Anagrams/Deranged anagrams
- Permutations/Derangements
- Find/Search/Determine
- ABC words
- Odd words
- Word ladder
- Semordnilap
- Word search
- Wordiff (game)
- String matching
- Tea cup rim text
- Alternade words
- Changeable words
- State name puzzle
- String comparison
- Unique characters
- Unique characters in each string
- Extract file extension
- Levenshtein distance
- Palindrome detection
- Common list elements
- Longest common suffix
- Longest common prefix
- Compare a list of strings
- Longest common substring
- Find common directory path
- Words from neighbour ones
- Change e letters to i in words
- Non-continuous subsequences
- Longest common subsequence
- Longest palindromic substrings
- Longest increasing subsequence
- Words containing "the" substring
- Sum of the digits of n is substring of n
- Determine if a string is numeric
- Determine if a string is collapsible
- Determine if a string is squeezable
- Determine if a string has all unique characters
- Determine if a string has all the same characters
- Longest substrings without repeating characters
- Find words which contains all the vowels
- Find words which contains most consonants
- Find words which contains more than 3 vowels
- Find words which first and last three letters are equals
- Find words which odd letters are consonants and even letters are vowels or vice_versa
- Formatting
- Substring
- Rep-string
- Word wrap
- String case
- Align columns
- Literals/String
- Repeat a string
- Brace expansion
- Brace expansion using ranges
- Reverse a string
- Phrase reversals
- Comma quibbling
- Special characters
- String concatenation
- Substring/Top and tail
- Commatizing numbers
- Reverse words in a string
- Suffixation of decimal numbers
- Long literals, with continuations
- Numerical and alphabetical suffixes
- Abbreviations, easy
- Abbreviations, simple
- Abbreviations, automatic
- Song lyrics/poems/Mad Libs/phrases
- Mad Libs
- Magic 8-ball
- 99 Bottles of Beer
- The Name Game (a song)
- The Old lady swallowed a fly
- The Twelve Days of Christmas
- Tokenize
- Text between
- Tokenize a string
- Word break problem
- Tokenize a string with escaping
- Split a character string based on change of character
- Sequences
C++
<lang cpp>#include <map>
- include <iostream>
- include <string>
int main() {
std::map<char, std::string> rep = {{'a', "DCaBA"}, // replacement string is reversed {'b', "E"}, {'r', "Fr"}};
std::string magic = "abracadabra";
for(auto it = magic.begin(); it != magic.end(); ++it) { if(auto f = rep.find(*it); f != rep.end() && !f->second.empty()) { *it = f->second.back(); f->second.pop_back(); } }
std::cout << magic << "\n";
}</lang>
- Output:
AErBcadCbFD
Factor
<lang factor>USING: assocs formatting grouping kernel random sequences ;
CONSTANT: instrs {
CHAR: a 1 CHAR: A CHAR: a 2 CHAR: B CHAR: a 4 CHAR: C CHAR: a 5 CHAR: D CHAR: b 1 CHAR: E CHAR: r 2 CHAR: F
}
- counts ( seq -- assoc )
H{ } clone swap [ 2dup swap inc-at dupd of ] zip-with nip ;
- replace-nths ( seq instrs -- seq' )
[ counts ] dip 3 group [ f suffix 2 group ] map substitute keys ;
- test ( str -- )
dup instrs replace-nths "" like "%s -> %s\n" printf ;
"abracadabra" test
"abracadabra" randomize test</lang>
- Output:
abracadabra -> AErBcadCbFD caaarrbabad -> cABarFECbDd
Go
<lang go>package main
import (
"fmt" "strings"
)
func main() {
s := "abracadabra" ss := []byte(s) var ixs []int for ix, c := range s { if c == 'a' { ixs = append(ixs, ix) } } repl := "ABaCD" for i := 0; i < 5; i++ { ss[ixs[i]] = repl[i] } s = string(ss) s = strings.Replace(s, "b", "E", 1) s = strings.Replace(s, "r", "F", 2) s = strings.Replace(s, "F", "r", 1) fmt.Println(s)
}</lang>
- Output:
AErBcadCbFD
J
<lang J> upd=: {{ x (n{I.y=m)} y }}
'ABCD' 'a' upd 0 1 3 4 'E' 'b' upd 0 'F' 'r' upd 1 'abracadabra'
AErBcadCbFD</lang>
upd here takes four arguments -- two on the left (replacement characters, original character) and two on the right(index values for which instances to replace, and the original string).
Julia
<lang ruby> rep = Dict('a' => Dict(1 => 'A', 2 => 'B', 4 => 'C', 5 => 'D'), 'b' => Dict(1 => 'E'), 'r' => Dict(2 => 'F'))
function trstring(oldstring, repdict)
seen, newchars = Dict{Char, Int}(), Char[] for c in oldstring i = get!(seen, c, 1) push!(newchars, haskey(repdict, c) && haskey(repdict[c], i) ? repdict[c][i] : c) seen[c] += 1 end return String(newchars)
end
println("abracadabra -> ", trstring("abracadabra", rep))
</lang>
- Output:
Same as Perl.
Perl
<lang perl>use strict; use warnings; use feature 'say';
sub transmogrify {
my($str, %sub) = @_; for my $l (keys %sub) { $str =~ s/$l/$_/ for split , $sub{$l}; $str =~ s/_/$l/g; } $str
}
my $word = 'abracadabra'; say "$word -> " . transmogrify $word, 'a' => 'AB_CD', 'r' => '_F', 'b' => 'E';</lang>
- Output:
abracadabra -> AErBcadCbFD
Phix
Couldn't really decide which I prefer so posted both.
with javascript_semantics function replace_nth(string s, r) string res = s for i=1 to length(r) by 3 do res[find_all(r[i],s)[r[i+1]-'0']] = r[i+2] end for return res end function ?replace_nth("abracadabra","a1Aa2Ba4Ca5Db1Er2F") -- Alternative version function replace_nths(string s, sequence r) for icr in r do {sequence idx, integer ch, string reps} = icr s = reinstate(s,extract(find_all(ch,s),idx),reps) end for return s end function constant r = {{{1,2,4,5},'a',"ABCD"}, {{1},'b',"E"}, {{2},'r',"F"}} ?replace_nths("abracadabra",r)
- Output:
"AErBcadCbFD" "AErBcadCbFD"
Raku
Set up to not particularly rely on absolute structure of the word. Demonstrate with both the original 'abracadabra' and with a random shuffled instance.
<lang perl6>sub mangle ($str is copy) {
$str.match(:ex, 'a')».from.map: { $str.substr-rw($_, 1) = 'ABaCD'.comb[$++] }; $str.=subst('b', 'E'); $str.substr-rw($_, 1) = 'F' given $str.match(:ex, 'r')».from[1]; $str
}
say $_, ' -> ', .&mangle given 'abracadabra';
say $_, ' -> ', .&mangle given 'abracadabra'.comb.pick(*).join;</lang>
- Output:
abracadabra -> AErBcadCbFD caarabadrab -> cABraECdFDb
Vlang
A similar approach to the C++ entry. <lang ruby>fn selectively_replace_chars(s string, char_map map[string]string) string {
mut bytes := s.bytes() mut counts := { 'a': 0 'b': 0 'r': 0 } for i := s.len - 1; i >= 0; i-- { c := s[i].ascii_str() if c in ['a', 'b', 'r'] { bytes[i] = char_map[c][counts[c]] counts[c]++ } } return bytes.bytestr()
}
fn main() {
char_map := { 'a': 'DCaBA' 'b': 'bE' 'r': 'Fr' } for old in ['abracadabra', 'caaarrbabad'] { new := selectively_replace_chars(old, char_map) println('$old -> $new') }
}</lang>
- Output:
abracadabra -> AErBcadCbFD caaarrbabad -> cABarFECbDd
Wren
Not particularly succinct but, thanks to a recently added library method, better than it would have been :) <lang ecmascript>import "./seq" for Lst import "./str" for Str
var s = "abracadabra" var sl = s.toList var ixs = Lst.indicesOf(sl, "a")[2] var repl = "ABaCD" for (i in 0..4) sl[ixs[i]] = repl[i] s = sl.join() s = Str.replace(s, "b", "E", 1) s = Str.replace(s, "r", "F", 2, 1) System.print(s)</lang>
- Output:
AErBcadCbFD
Alternatively, using regular expressions (embedded script) producing output as before. <lang ecmascript>import "./regex" for Regex
var s = "abracadabra" var split = Regex.compile("a").split(s) var repl = "ABaCD" var res = "" for (i in 0...split.count-1) res = res + split[i] + repl[i] s = res + split[-1] s = Regex.compile("b").replace(s, "E") s = Regex.compile("r").replaceAll(s, "F", 2, 1) System.print(s)</lang>
XPL0
<lang XPL0>string 0; proc Mangle(S); char S, A, B, R; [A:= "ABaCD"; B:= "Eb"; R:= "rF"; while S(0) do
[case S(0) of ^a: [S(0):= A(0); A:= A+1]; ^b: [S(0):= B(0); B:= B+1]; ^r: [S(0):= R(0); R:= R+1] other []; S:= S+1; ];
];
char S; [S:= "abracadabra"; Text(0, S); Text(0, " -> "); Mangle(S); Text(0, S); CrLf(0); S:= "caarabadrab"; Text(0, S); Text(0, " -> "); Mangle(S); Text(0, S); CrLf(0); ]</lang>
- Output:
abracadabra -> AErBcadCbFD caarabadrab -> cABraECdFDb