Comma quibbling: Difference between revisions

m
→‎{{header|PHP}}: fix formatting.
m (→‎{{header|PHP}}: fix formatting.)
 
(25 intermediate revisions by 14 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 524 ⟶ 586:
ABC DEF : {ABC and DEF}
ABC DEF G H : {ABC, DEF, G and H}</pre>
 
=={{header|APL}}==
<syntaxhighlight lang="APL">quibble ← 1⌽'}{',(∊⊢,¨2↓(' and ' ''),⍨(⊂', ')⍴⍨⍴)</syntaxhighlight>
{{out}}
<pre> quibble ⍬
{}
quibble ⊂'ABC'
{ABC}
quibble 'ABC' 'DEF'
{ABC and DEF}
quibble 'ABC' 'DEF' 'G' 'H'
{ABC, DEF, G and H}</pre>
 
=={{header|AppleScript}}==
Line 723 ⟶ 797:
 
=={{header|Arturo}}==
<syntaxhighlight lang="rebol">quibble: function $[seqsequence :block][
if? 0 =size seq ->size "{}"sequence
-> return "{}"
else [
if? 1=size seq -> "{" ++ seq\0 ++ "}"
if? 1 = size sequence
else -> "{" ++ (join.with:", " slice seq 0 (size seq)-1) ++ " and " ++ (last seq) ++ "}"
-> return ~"{|sequence\0|}"
]
last: pop 'sequence
return ~« {|join.with: ", " sequence| and |last|}
]
 
Line 746 ⟶ 823:
<pre>{}
{ABC}
{ABC, DEF and DEF}
{ABC, DEF, G, H and H}</pre>
 
=={{header|Astro}}==
Line 1,241 ⟶ 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,346 ⟶ 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,390 ⟶ 1,541:
{ABC and DEF}
{ABC, DEF, G and H}</pre>
 
=={{header|Delphi}}==
See [[#Pascal|Pascal]].
Line 1,413 ⟶ 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,824 ⟶ 2,000:
 
=={{header|FutureBasic}}==
Long solution:
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
Line 1,860 ⟶ 2,037:
NSLog( @"%@", fn CommaQuibber( @"[\"ABC\", \"DEF\"]" ) )
NSLog( @"%@", fn CommaQuibber( @"[\"ABC\", \"DEF\", \"G\", \"H\"]" ) )
 
HandleEvents
</syntaxhighlight>
Short solution:
<syntaxhighlight lang="futurebasic">
local fn CommaQuibbler( s as CFArrayRef ) as CFStringRef
CFStringRef result = NULL
select ( len(s) )
case 0: exit fn = @"{}"
case 1: exit fn = fn StringWithFormat( @"{%@}", s[0] )
case 2: exit fn = fn StringWithFormat( @"{%@ and %@}", s[0], s[1] )
case else
result = fn StringWithFormat( @"{%@}", fn ArrayComponentsJoinedByString( s, @", " ) )
CFRange lastComma = fn StringRangeOfStringWithOptions( result, @",", NSBackwardsSearch )
result = fn StringByReplacingCharactersInRange( result, lastComma, @" and" )
end select
end fn = result
 
print fn CommaQuibbler( @[] )
print fn CommaQuibbler( @[@"ABC"] )
print fn CommaQuibbler( @[@"ABC", @"DEF"] )
print fn CommaQuibbler( @[@"ABC", @"DEF", @"G", @"H"] )
 
HandleEvents
Line 1,974 ⟶ 2,174:
Or, defining just two cases, and drawing more on standard libraries than on hand-crafted pattern-matching and recursion:
<syntaxhighlight lang="haskell">import Data.List (intercalate)
 
--------------------- COMMA QUIBBLING --------------------
 
quibble :: [String] -> String
quibble ws@(_ : _ : _) =
intercalate
| length ws > 1 =
intercalate" and "
( [intercalate ", " . reverse . tail, head]
" and "
([intercalate ", " . reverse . tail, head] <*> [reverse ws])
)
| otherwise = concat ws
quibble xs = concat xs
 
--------------------------- TEST -------------------------
main :: IO ()
main =
mapM_ (putStrLn . (`intercalate` ["{", "}"]) . quibble) $
[[], ["ABC"], ["ABC", "DEF"], ["ABC", "DEF", "G", "H"]] ++
<> ( words
(words <$> ["One two three four", "Me myself I", "Jack Jill", "Loner"])
<$> [ "One two three four",
</syntaxhighlight>
"Me myself I",
"Jack Jill",
"Loner"
]
)</syntaxhighlight>
{{Out}}
<pre>{}
Line 2,333 ⟶ 2,542:
["ABC", "DEF"] -> {ABC and DEF}
["ABC", "DEF", "G", "H"] -> {ABC, DEF, G and H}
</pre>
 
=={{header|Lang}}==
<syntaxhighlight lang="lang">
fp.quibble = (&words) -> {
$len $= @&words
$output = \{\e
$i
repeat($[i], $len) {
$output += &words[$i] ||| ($i == -|$len?\e:($i == $len - 2?\sand\s:\,\s))
}
$output += \}\e
return $output
}
 
fn.println(fp.quibble(fn.arrayOf()))
fn.println(fp.quibble(fn.arrayOf(ABC)))
fn.println(fp.quibble(fn.arrayOf(ABC, DEF)))
fn.println(fp.quibble(fn.arrayOf(ABC, DEF, G, H)))
</syntaxhighlight>
 
{{out}}
<pre>
{}
{ABC}
{ABC and DEF}
{ABC, DEF, G and H}
</pre>
 
Line 2,688 ⟶ 2,928:
</syntaxhighlight>
 
=={{header|Miranda}}==
<syntaxhighlight lang="miranda">main :: [sys_message]
main = [Stdout (show test ++ ": {" ++ quibble test ++ "}\n") | test <- tests]
 
tests :: [[[char]]]
tests = [ [],
["ABC"],
["ABC","DEF"],
["ABC","DEF","G","H"] ]
 
quibble :: [[char]]->[char]
quibble [] = []
quibble [word] = word
quibble [word1,word2] = word1 ++ " and " ++ word2
quibble (word:words) = word ++ ", " ++ quibble words</syntaxhighlight>
{{out}}
<pre>[]: {}
["ABC"]: {ABC}
["ABC","DEF"]: {ABC and DEF}
["ABC","DEF","G","H"]: {ABC, DEF, G and H}</pre>
=={{header|NetRexx}}==
<syntaxhighlight lang="netrexx">/* NetRexx */
Line 3,105 ⟶ 3,365:
=={{header|Perl}}==
{{trans|Raku}}
<syntaxhighlight lang="perl">sub comma_quibbling :prototype(@) {
return "{$_}" for
@_ < 2 ? "@_" :
Line 3,122 ⟶ 3,382:
 
<syntaxhighlight lang="perl">use 5.01;
sub comma_quibbling {
my $last = pop // '';
return '{'. (@_ ? (join ', ', @_).' and '.$last : $last).'}';
Line 3,165 ⟶ 3,425:
<syntaxhighlight lang="php"><?php
 
function quibble($arr) {
 
$words = switch (count($arr);) {
 
case 0:
if($words == 0){
return '{}';
 
}elseif($words == 1){
case 1:
return '{'.$arr[0].'}';
return "{{$arr[0]}}";
}elseif($words == 2){
 
return '{'.$arr[0].' and '.$arr[1].'}';
default:
}else{
return '{'. $left = implode(', ', array_splicearray_slice($arr, 0, -1) ). ' and '.$arr[0].'}';
$right = array_slice($arr, -1)[0];
}
return "{{$left} and {$right}}";
 
}
 
}
Line 3,191 ⟶ 3,454:
foreach ($tests as $test) {
echo quibble($test) . PHP_EOL;
}
}</syntaxhighlight>
?></syntaxhighlight>
{{out}}
<pre>{}
Line 3,771 ⟶ 4,035:
{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 3,909 ⟶ 4,197:
{ABC DEF}
{ABC, DEF, G and H}
</pre>
 
=={{header|RPL}}==
Whilst it is always important to ensure overall code clarity for maintenance by using explicit variable names and structured control flows, the spirit of reverse Polish notation programming is to optimize some key part of the algorithm in order to make it as compact - and possibly as fast - as possible, whatever the induced loss of readability. Here, two <code>IFTE</code> low-level instructions are nested to deliver the appropriate liaison substring between two words or before the first word.
{{works with|Halcyon Calc|4.2.7}}
≪ DUP SIZE → words n
≪ "{" 1
'''WHILE''' DUP n ≤ '''REPEAT'''
DUP 1 ≠ OVER n ≠ ", " " and " '''IFTE''' "" '''IFTE'''
ROT SWAP +
words 3 PICK GET +
SWAP 1 +
'''END'''
DROP "}" +
≫ ≫ 'CMAQBL' STO
{{in}}
<pre>
{ } CMAQBL
{ "ABC" } CMAQBL
{ "ABC", "DEF" } CMAQBL
{ "ABC", "DEF", "G", "H" } CMAQBL
</pre>
{{out}}
<pre>
4: "{}"
3: "{ABC}"
2: "{ABC and DEF}"
1: "{ABC, DEF, G and H}"
</pre>
 
Line 4,102 ⟶ 4,418:
{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) {
'{' + ([words.ftfirst(0, -21).join(', ')]-[''] + [words.last] -> join(' and ')) + '}';
}
 
[<>, <ABC>, <ABC DEF>, <ABC DEF G H>].each { |w|
say comma_quibbling(w);
}</syntaxhighlight>
{{out}}
Line 4,185 ⟶ 4,535:
(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}}
{{trans|AWK}}
{{works with|Korn Shell}}
<syntaxhighlight lang="bash">quibble() {
{{works with|Z Shell}}
# Here awk(1) is easier than sed(1).
<syntaxhighlight lang="bash">
awk 'BEGIN {
quibble() {
for (i = 1; i < ARGC - 2; i++) s = s ARGV[i] ", "
printf '{'
i = ARGC - 2; if (i > 0) s = s ARGV[i] " and "
i = ARGC - 1; ifwhile (i( $# > 0)2 s = s)); ARGV[i]do
printf "{'%s}\n", s' "$1"
shift
exit 0
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,324 ⟶ 4,727:
{ABC, DEF, G and H}</pre>
 
=={{header|V (Vlang)}}==
{{trans|go}}
<syntaxhighlight lang="v (vlang)">fn q(s []string) string {
match s.len {
0 {
Line 4,358 ⟶ 4,761:
 
=={{header|Wren}}==
<syntaxhighlight lang="ecmascriptwren">var quibbling = Fn.new { |w|
var c = w.count
if (c == 0) return "{}"
1,480

edits