Comma quibbling: Difference between revisions
Content deleted Content added
m →{{header|Sidef}}: update |
Add ed example |
||
(15 intermediate revisions by 6 users not shown) | |||
Line 223:
{ABC and DEF}
{ABC, DEF, G and H}</pre>
=={{header|ABC}}==
<syntaxhighlight lang="ABC">HOW TO RETURN quibble words:
PUT "" IN result
PUT #words IN remaining
FOR word IN words:
PUT result^word IN result
PUT remaining-1 IN remaining
IF remaining = 1: PUT result^" and " IN result
IF remaining > 1: PUT result^", " IN result
RETURN "{" ^ result ^ "}"
PUT {} IN tests
INSERT {} IN tests
INSERT {[1]: "ABC"} IN tests
INSERT {[1]: "ABC"; [2]: "DEF"} IN tests
INSERT {[1]: "ABC"; [2]: "DEF"; [3]: "G"; [4]: "H"} IN tests
FOR test IN tests:
WRITE quibble test/</syntaxhighlight>
{{out}}
<pre>{}
{ABC}
{ABC and DEF}
{ABC, DEF, G and H}</pre>
=={{header|Acornsoft Lisp}}==
There's no string data type; symbols are used instead. The <code>implode</code> function is used to concatenate a list of symbols. When writing a symbol in source code, exclamation mark is an escape character that allows characters such as spaces and exclamation marks to be treated as part of the symbol's name.
<syntaxhighlight lang="lisp">
(defun examples ()
(map '(lambda (words) (printc (quibble words)))
'(() (ABC) (ABC DEF) (ABC DEF G H))))
(defun quibble (words)
(implode (list '{ (quibbles words) '})))
(defun quibbles (words)
(implode (conjunction words)))
(defun conjunction (words)
(cond ((null words)
'())
((null (cdr words))
words)
((null (cddr words))
(list (car words) '! and! (cadr words)))
(t
(cons (car words)
(cons ',! (conjunction (cdr words)))))))
</syntaxhighlight>
{{out}}
Calling <code>(examples)</code> will output:
<pre>
{}
{ABC}
{ABC and DEF}
{ABC, DEF, G and H}
</pre>
=={{header|Action!}}==
Line 1,256 ⟶ 1,318:
{ABC and DEF}
{ABC, DEF, G and H}</pre>
=={{header|Commodore BASIC}}==
The Commodore character set has no curly braces, so I substituted square brackets. The solution could no doubt be improved, but some of the elegance of other solutions is not possible simply because a FOR loop always executes at least once, even if its parameters would seem to indicate that it should not.
<syntaxhighlight lang="basic">100 DIM A$(3)
110 FOR TC=1 TO 4
120 : READ A: IF A=0 THEN 160
130 : FOR I=0 TO A-1
140 : READ A$(I)
150 : NEXT I
160 : GOSUB 200
170 : PRINT CQ$
180 NEXT TC
190 END
200 CQ$="["
210 IF A < 1 THEN 290
220 CQ$ = CQ$ + A$(0)
230 IF A < 2 THEN 290
240 IF A < 3 THEN 280
250 FOR I=1 TO A - 2
260 : CQ$ = CQ$ + ", " + A$(I)
270 NEXT I
280 CQ$ = CQ$ + " AND " + A$(A - 1)
290 CQ$ = CQ$ + "]"
300 RETURN
310 DATA 0
320 DATA 1, ABC
330 DATA 2, ABC, DEF
340 DATA 4, ABC, DEF, G, H
</syntaxhighlight>
{{out}}
<pre>[]
[ABC]
[ABC AND DEF]
[ABC, DEF, G AND H]</pre>
=={{header|Common Lisp}}==
Line 1,361 ⟶ 1,457:
{{out}}
<pre>["{}", "{ABC}", "{ABC and DEF}", "{ABC, DEF, G and H}"]</pre>
=={{header|dc}}==
<syntaxhighlight lang="dc">[(q)uibble: main entry point. print brackets, calling n in between if stack not
empty.]sx
[ [{]n z 0 !=n [}]pR ]sq
[(n)onempty: if more than 1 item, call m. then print top of stack.]sx
[ z 1 !=m n ]sn
[(m)ore: call f to flip stack into r register, call p to print most of it,
then pop the last item back onto the main stack so it's there to be printed
after we return]sx
[ lfx lpx Lr ]sm
[(f)lip: utility routine to reverse the stack into the r register]sx
[ Sr z 0 !=f ]sf
[(p)rint: get next item from stack in r register and print it. If there are
more than 2 items left on the register stack (which never drops below one
item), print a comma (c) and recurse. If there are exactly two items left,
print " and " (a) and return.]sx
[ Lr n 2 yr >c 2 yr =a 2 yr >p]sp
[(c)omma: utility routine to print a comma followed by a space]sx
[ [, ]n ]sc
[(a)and: utility routine to print " and "]sx
[ [ and ]n ]sa
[run tests]sx
lqx
[ABC] lqx
[ABC] [DEF] lqx
[ABC] [DEF] [G] [H] lqx</syntaxhighlight>
{{out}}
<pre>{}
{ABC}
{ABC and DEF}
{ABC, DEF, G and H}</pre>
=={{header|DCL}}==
Line 1,405 ⟶ 1,541:
{ABC and DEF}
{ABC, DEF, G and H}</pre>
=={{header|Delphi}}==
See [[#Pascal|Pascal]].
Line 1,428 ⟶ 1,565:
"{ABC and DEF}"
"{ABC, DEF, G and H}"</pre>
=={{header|EasyLang}}==
<syntaxhighlight>
func$ tolist s$ .
s$[] = strsplit s$ " "
r$ = "{"
n = len s$[]
for i = 1 to n - 2
r$ &= s$[i] & ", "
.
if n > 0
if n > 1
r$ &= s$[n - 1] & " and "
.
r$ &= s$[n]
.
r$ &= "}"
return r$
.
print tolist ""
print tolist "ABC"
print tolist "ABC DEF"
print tolist "ABC DEF G H"
</syntaxhighlight>
=={{header|EchoLisp}}==
Line 1,452 ⟶ 1,613:
("ABC" "DEF" "G" "H") ----> "{ ABC, DEF, G and H }"
</syntaxhighlight>
=={{header|ed}}==
Uses basic regular expressions (BREs).
<syntaxhighlight lang="sed">
# by Artyom Bologov
H
,p
g/.*/s/ /, /g
g/[,]/s/,\([^,]*\)$/ and\1/
g/.*/s//{&}/
,p
Q
</syntaxhighlight>
{{out}}
<pre>$ ed -s comma-quibling.input < comma-quibling.ed
Newline appended
ABC
ABC DEF
ABC DEF G H
{}
{ABC}
{ABC and DEF}
{ABC, DEF, G and H}</pre>
=={{header|Eiffel}}==
Line 3,264 ⟶ 3,453:
<syntaxhighlight lang="php"><?php
function quibble($arr) {
case 0:
return '{}';
case 1:
return "{{$arr[0]}}";
default:
$right = array_slice($arr, -1)[0];
return "{{$left} and {$right}}";
}
}
Line 3,290 ⟶ 3,482:
foreach ($tests as $test) {
echo quibble($test) . PHP_EOL;
}
?></syntaxhighlight>
{{out}}
<pre>{}
Line 3,870 ⟶ 4,063:
{ABC and DEF}
{ABC, DEF, G, and H}</pre>
=={{header|Refal}}==
<syntaxhighlight lang="refal">$ENTRY Go {
= <Prout <Quibble>>
<Prout <Quibble ('ABC')>>
<Prout <Quibble ('ABC') ('DEF')>>
<Prout <Quibble ('ABC') ('DEF') ('G') ('H')>>;
};
Quibble {
e.X = '{' <Quibble1 e.X> '}';
};
Quibble1 {
= ;
(e.Word) = e.Word;
(e.Word1) (e.Word2) = e.Word1 ' and ' e.Word2;
(e.Word) e.Words = e.Word ', ' <Quibble1 e.Words>;
};</syntaxhighlight>
{{out}}
<pre>{}
{ABC}
{ABC and DEF}
{ABC, DEF, G and H}</pre>
=={{header|REXX}}==
Line 4,229 ⟶ 4,446:
{ABC, DEF, G and H}
</pre>
=={{header|SETL}}==
<syntaxhighlight lang="setl">program comma_quibbling;
tests := [
[],
["ABC"],
["ABC","DEF"],
["ABC","DEF","G","H"]
];
loop for t in tests do
print(t, "=", quibble(t));
end loop;
proc quibble(words);
ret := '{';
loop while words /= [] do
word fromb words;
ret +:= word;
case of
(#words = 1):
ret +:= " and ";
(#words > 1):
ret +:= ", ";
end case;
end loop;
return ret + '}';
end proc;
end program;</syntaxhighlight>
{{out}}
<pre>[] = {}
[ABC] = {ABC}
[ABC DEF] = {ABC and DEF}
[ABC DEF G H] = {ABC, DEF, G and H}</pre>
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">func comma_quibbling(words) {
Line 4,312 ⟶ 4,563:
(tree-bind (: last . lead) (reverse list)
`{@{(nreverse lead) ", "}@(if lead " and ")@last}`))</syntaxhighlight>
=={{header|Uiua}}==
{{works with|Uiua|0.10.0-dev.1}}
<syntaxhighlight lang="Uiua">
Tests ← {{}
{"ABC"}
{"ABC" "DEF"}
{"ABC" "DEF" "G" "H"}}
Jam ← ◇⊂◇⊂:□
Quibble ← |1 ⟨""◌|°□⊢|Jam" and "°⊟|Quibble⊂⊃(□Jam", "°⊟↙2)(↘2)⟩↧3⧻.
Wrap ← ⊂⊂"{" : "}" Quibble
⍚(&pWrap) Tests
</syntaxhighlight>
=={{header|UNIX Shell}}==
{{works with|Bourne Again SHell}}
{{works with|Korn Shell}}
{{works with|Z Shell}}
<syntaxhighlight lang="bash">
quibble() {
printf '{'
shift
done
if (( $# )); then
printf '%s' "$1"
shift
fi
if (( $# )); then
printf ' and %s' "$1"
fi
printf '%s\n' '}'
}</syntaxhighlight>
With a slight modification, it will work in any POSIX shell, or even older Bourne-compatible shells as long as they have functions and <b>printf</b>:
<syntaxhighlight lang="sh">
quibble() {
printf '{'
while [ $# -gt 2 ]; do
printf '%s, ' "$1"
shift
done
if [ $# -gt 0 ]; then
printf '%s' "$1"
shift
fi
if [ $# -gt 0 ]; then
printf ' and %s' "$1"
fi
printf '%s\n' '}'
}</syntaxhighlight>
Going the other way, Zsh-specific code can be more compact:
{{works with|Z Shell}}
<syntaxhighlight lang="zsh">quibble() {
printf '{'
if (( $# > 1 )) printf '%s and ' ${(j:, :)@[1,-2]}
printf '%s}\n' $@[-1]
}</syntaxhighlight>
The test code is the same either way:
<syntaxhighlight lang="sh">
quibble
quibble ABC
Line 4,485 ⟶ 4,789:
=={{header|Wren}}==
<syntaxhighlight lang="
var c = w.count
if (c == 0) return "{}"
|