Comma quibbling: Difference between revisions
Walterpachl (talk | contribs) m moved PL/I |
|||
Line 204:
{ABC and DEF}
{ABC, DEF, G and H}</pre>
=={{header|Python}}==▼
===replace() whilst reversed===▼
replace(..) can only replace the first X occurrences not the last▼
hence the replace is done on the reverse of the intermediate string▼
then reversed back.▼
<lang python>>>> def strcat(sequence):▼
return '{%s}' % ', '.join(sequence)[::-1].replace(',', 'dna ', 1)[::-1]▼
>>> for seq in ([], ["ABC"], ["ABC", "DEF"], ["ABC", "DEF", "G", "H"]):▼
print('Input: %-24r -> Output: %r' % (seq, strcat(seq)))▼
Input: [] -> Output: '{}'▼
Input: ['ABC'] -> Output: '{ABC}'▼
Input: ['ABC', 'DEF'] -> Output: '{ABC and DEF}'▼
Input: ['ABC', 'DEF', 'G', 'H'] -> Output: '{ABC, DEF, G and H}'▼
>>> </lang>▼
===Counted replacement===▼
(Possible){{trans|Tcl}}▼
replace() will replace nothing if the count of items to replace is zero, (and negative integer counts act to replace all occurrences).▼
This combines with the length of the input sequence to allow this to work:▼
<lang python>def commaQuibble(s):▼
return '{%s}' % ' and '.join(s).replace(' and ', ', ', len(s) - 2)▼
for seq in ([], ["ABC"], ["ABC", "DEF"], ["ABC", "DEF", "G", "H"]):▼
print('Input: %-24r -> Output: %r' % (seq, commaQuibble(seq)))</lang>▼
{{out}}▼
<pre>Input: [] -> Output: '{}'▼
Input: ['ABC'] -> Output: '{ABC}'▼
Input: ['ABC', 'DEF'] -> Output: '{ABC and DEF}'▼
Input: ['ABC', 'DEF', 'G', 'H'] -> Output: '{ABC, DEF, G and H}'</pre>▼
=={{header|PL/I}}==
Line 286 ⟶ 252:
{ABC, DEF, G, H}
</pre>
▲=={{header|Python}}==
▲===replace() whilst reversed===
▲replace(..) can only replace the first X occurrences not the last
▲hence the replace is done on the reverse of the intermediate string
▲then reversed back.
▲<lang python>>>> def strcat(sequence):
▲ return '{%s}' % ', '.join(sequence)[::-1].replace(',', 'dna ', 1)[::-1]
▲>>> for seq in ([], ["ABC"], ["ABC", "DEF"], ["ABC", "DEF", "G", "H"]):
▲ print('Input: %-24r -> Output: %r' % (seq, strcat(seq)))
▲Input: [] -> Output: '{}'
▲Input: ['ABC'] -> Output: '{ABC}'
▲Input: ['ABC', 'DEF'] -> Output: '{ABC and DEF}'
▲Input: ['ABC', 'DEF', 'G', 'H'] -> Output: '{ABC, DEF, G and H}'
▲>>> </lang>
▲===Counted replacement===
▲(Possible){{trans|Tcl}}
▲replace() will replace nothing if the count of items to replace is zero, (and negative integer counts act to replace all occurrences).
▲This combines with the length of the input sequence to allow this to work:
▲<lang python>def commaQuibble(s):
▲ return '{%s}' % ' and '.join(s).replace(' and ', ', ', len(s) - 2)
▲for seq in ([], ["ABC"], ["ABC", "DEF"], ["ABC", "DEF", "G", "H"]):
▲ print('Input: %-24r -> Output: %r' % (seq, commaQuibble(seq)))</lang>
▲{{out}}
▲<pre>Input: [] -> Output: '{}'
▲Input: ['ABC'] -> Output: '{ABC}'
▲Input: ['ABC', 'DEF'] -> Output: '{ABC and DEF}'
▲Input: ['ABC', 'DEF', 'G', 'H'] -> Output: '{ABC, DEF, G and H}'</pre>
=={{header|REXX}}==
|
Revision as of 08:07, 7 October 2013
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
Comma quibbling is a task originally set by Eric Lippert in his blog.
The task is to write a function to generate a string output which is the concatenation of input words from a list/sequence where:
- An input of no words produces the output string of just the two brace characters "{}".
- An input of just one word, e.g. ["ABC"], produces the output string of the word inside the two braces, e.g. "{ABC}".
- An input of two words, e.g. ["ABC", "DEF"], produces the output string of the two words inside the two braces with the words separated by the string " and ", e.g. "{ABC and DEF}".
- An input of three or more words, e.g. ["ABC", "DEF", "G", "H"], produces the output string of all but the last word separated by ", " with the last word separated by " and " and all within braces; e.g. "{ABC, DEF, G and H}".
Test your function with the following series of inputs showing your output here on this page:
- [] # (No input words).
- ["ABC"]
- ["ABC", "DEF"]
- ["ABC", "DEF", "G", "H"]
Note: Assume words are non-empty strings of uppercase characters for this task.
AWK
<lang awk>function quibble(a, n, i, s) { for (i = 1; i < n - 1; i++) s = s a[i] ", " i = n - 1; if (i > 0) s = s a[i] " and " if (n > 0) s = s a[n] return "{" s "}" }
BEGIN { print quibble(a, 0) n = split("ABC", b); print quibble(b, n) n = split("ABC DEF", c); print quibble(c, n) n = split("ABC DEF G H", d); print quibble(d, n) }</lang>
- Output:
{} {ABC} {ABC and DEF} {ABC, DEF, G and H}
C#
<lang csharp>public static string Quibble(string[] input) {
var len = input.Length; return "{" + String.Join("", input.Take(len - 2).Select(n => n + ", ") .Concat(input.Skip(len < 2 ? len : len - 2).Take(1).Select(n => n + " and "))) + (input.LastOrDefault() ?? "") + "}";
}
static void Main(string[] args) {
Console.WriteLine(Quibble(new string[] { })); Console.WriteLine(Quibble(new[] { "A" })); Console.WriteLine(Quibble(new[] { "A", "B" })); Console.WriteLine(Quibble(new[] { "A", "B", "C" })); Console.WriteLine(Quibble(new[] { "A", "B", "C", "D" })); Console.WriteLine(Quibble(new[] { "A", "B", "C", "D", "E" }));
}</lang>
- Output:
{} {A} {A and B} {A, B and C} {A, B, C and D} {A, B, C, D and E}
C++
<lang cpp>#include <iostream>
template<class T> void quibble(std::ostream& o, T i, T e) {
o << "{"; if (e != i) { T n = i++; const char* more = ""; while (e != i) { o << more << *n; more = ", "; n = i++; } o << (*more?" and ":"") << *n; } o << "}";
}
int main(int argc, char** argv) {
char const* a[] = {"ABC","DEF","G","H"}; for (int i=0; i<5; i++) { quibble(std::cout, a, a+i); std::cout << std::endl; } return 0;
}</lang>
- Output:
{} {ABC} {ABC and DEF} {ABC, DEF and G} {ABC, DEF, G and H}
Clojure
<lang clojure> (defn quibbling [sequence]
(let [sep (if (> (count sequence) 1) " and " "")] (apply str (concat (interpose ", " (butlast sequence)) [sep (last sequence)]))))
(map quibbling [[]
["ABC"] ["ABC", "DEF"] ["ABC", "DEF", "G", "H"]])
</lang>
- Output:
("" "ABC" "ABC and DEF" "ABC, DEF, G and H")
D
<lang d>import std.stdio, std.string;
string quibbler(in string[] seq) pure /*nothrow*/ {
if (seq.length <= 1) return format("{%-(%s, %)}", seq); else return format("{%-(%s, %) and %s}", seq[0 .. $-1], seq[$-1]);
}
void main() {
//foreach (immutable test; [[], foreach (const test; [[], ["ABC"], ["ABC", "DEF"], ["ABC", "DEF", "G", "H"]]) test.quibbler.writeln;
}</lang>
- Output:
{} {ABC} {ABC and DEF} {ABC, DEF, G and H}
F#
<lang fsharp>let quibble list =
let rec inner = function | [] -> "" | [x] -> x | [x;y] -> sprintf "%s and %s" x y | h::t -> sprintf "%s, %s" h (inner t) sprintf "{%s}" (inner list)
// test interactively quibble [] quibble ["ABC"] quibble ["ABC"; "DEF"] quibble ["ABC"; "DEF"; "G"] quibble ["ABC"; "DEF"; "G"; "H"]</lang>
Mathematica
<lang Mathematica>quibble[words___] :=
ToString@{StringJoin@@ Replace[Riffle[{words}, ", "], {most__, ", ", last_} -> {most, " and ", last}]}</lang>
- Output:
In[2]:= quibble[] Out[2]= {} In[3]:= quibble["ABC"] Out[3]= {ABC} In[4]:= quibble["ABC","DEF"] Out[4]= {ABC and DEF} In[5]:= quibble["ABC","DEF","G","H"] Out[5]= {ABC, DEF, G and H}
Perl
<lang perl>sub comma_quibbling(@) {
return "{$_}" for @_ < 2 ? "@_" : join(', ', @_[0..@_-2]) . ' and ' . $_[-1];
}
print comma_quibbling(@$_), "\n" for
[], [qw(ABC)], [qw(ABC DEF)], [qw(ABC DEF G H)];</lang>
- Output:
{} {ABC} {ABC and DEF} {ABC, DEF, G and H}
Perl 6
<lang perl6>sub comma-quibbling(@A) {
<{ }>.join: @A < 2 ?? @A !! "@A[0..*-2].join(', ') and @A[*-1]";
}
say comma-quibbling($_) for
[], [<ABC>], [<ABC DEF>], [<ABC DEF G H>];</lang>
- Output:
{} {ABC} {ABC and DEF} {ABC, DEF, G and H}
PL/I
<lang pli>*process or(!);
quib: Proc Options(main); /********************************************************************* * 06.10.2013 Walter Pachl *********************************************************************/ put Edit(quibbling())(Skip,a); put Edit(quibbling('ABC'))(Skip,a); put Edit(quibbling('ABC DEF'))(Skip,a); put Edit(quibbling('ABC DEF G H'))(Skip,a); return;
quibbling: proc(s) Returns(Char(100) Var); Dcl s Char(*); Dcl result Char(100) Var; Dcl (wi,p) Bin Fixed(31); If s= Then result=; Else Do; Do wi=1 By 1 While(s^=); p=index(s,' '); If p=0 Then Do; If wi>1 Then result=result!!' and '!!s; else result=s; s=; End; Else Do; If wi=1 Then result=left(s,p-1); Else result=result!!', '!!left(s,p-1); s=substr(s,p+1); End; End; End; Return('{'!!result!!'}'); End; End;</lang>
- Output:
{} {ABC} {ABC, DEF} {ABC, DEF, G, H}
Python
replace() whilst reversed
replace(..) can only replace the first X occurrences not the last hence the replace is done on the reverse of the intermediate string then reversed back. <lang python>>>> def strcat(sequence):
return '{%s}' % ', '.join(sequence)[::-1].replace(',', 'dna ', 1)[::-1]
>>> for seq in ([], ["ABC"], ["ABC", "DEF"], ["ABC", "DEF", "G", "H"]):
print('Input: %-24r -> Output: %r' % (seq, strcat(seq)))
Input: [] -> Output: '{}'
Input: ['ABC'] -> Output: '{ABC}'
Input: ['ABC', 'DEF'] -> Output: '{ABC and DEF}'
Input: ['ABC', 'DEF', 'G', 'H'] -> Output: '{ABC, DEF, G and H}'
>>> </lang>
Counted replacement
(Possible)
replace() will replace nothing if the count of items to replace is zero, (and negative integer counts act to replace all occurrences). This combines with the length of the input sequence to allow this to work: <lang python>def commaQuibble(s):
return '{%s}' % ' and '.join(s).replace(' and ', ', ', len(s) - 2)
for seq in ([], ["ABC"], ["ABC", "DEF"], ["ABC", "DEF", "G", "H"]): print('Input: %-24r -> Output: %r' % (seq, commaQuibble(seq)))</lang>
- Output:
Input: [] -> Output: '{}' Input: ['ABC'] -> Output: '{ABC}' Input: ['ABC', 'DEF'] -> Output: '{ABC and DEF}' Input: ['ABC', 'DEF', 'G', 'H'] -> Output: '{ABC, DEF, G and H}'
REXX
<lang rexx>say quibbling() say quibbling('ABC') say quibbling('ABC DEF') say quibbling('ABC DEF G H') exit
quibbling: procedure
parse arg list Select When list= Then result= When words(list)=1 then result=word(list,1) Otherwise result=translate(strip(subword(list,1,words(list)-1)),',',' '), 'and' word(list,words(list)) End Return '{'result'}'</lang>
- Output:
{} {ABC} {ABC and DEF} {ABC,DEF,G and H}
Rust
<lang Rust>fn quibble(seq: &[~str]) -> ~str {
match seq { [] => ~"{}", [ref w] => fmt!("{%s}", *w), [..ws, ref w] => fmt!("{%s and %s}", ws.connect(", "), *w), }
}
fn main() {
println(quibble([])); println(quibble([~"ABC"])); println(quibble([~"ABC", ~"DEF"])); println(quibble([~"ABC", ~"DEF", ~"G", ~"H"]));
}</lang>
- Output:
{} {ABC} {ABC and DEF} {ABC, DEF, G and H}
Scala
<lang scala>def quibble( s:List[String] ) = s match {
case m if m.isEmpty => "{}" case m if m.length < 3 => m.mkString("{", " and ", "}") case m => "{" + m.init.mkString(", ") + " and " + m.last + "}"
}
// A little test... {
println( quibble( List() ) ) println( quibble( List("ABC") ) ) println( quibble( List("ABC","DEF") ) ) println( quibble( List("ABC","DEF","G","H") ) )
}</lang>
- Output:
{} {ABC} {ABC and DEF} {ABC, DEF, G and H}
Tcl
<lang tcl>proc commaQuibble {lst} {
return \{[join [lreplace $lst end-1 end [join [lrange $lst end-1 end] " and "]] ", "]\}
}
foreach input { {} {"ABC"} {"ABC" "DEF"} {"ABC" "DEF" "G" "H"} } {
puts [commaQuibble $input]
}</lang>
- Output:
{} {ABC} {ABC and DEF} {ABC, DEF, G and H}
UNIX Shell
<lang bash>quibble() { # Here awk(1) is easier than sed(1). awk 'BEGIN { for (i = 1; i < ARGC - 2; i++) s = s ARGV[i] ", " i = ARGC - 2; if (i > 0) s = s ARGV[i] " and " i = ARGC - 1; if (i > 0) s = s ARGV[i] printf "{%s}\n", s exit 0 }' "$@" }
quibble quibble ABC quibble ABC DEF quibble ABC DEF G H</lang>
- Output:
{} {ABC} {ABC and DEF} {ABC, DEF, G and H}