I'm trying to find combinations of characters that fit a (c)v pattern for up to n syllables, and so started by using expansion like echo {,p,t}{a,i}
for all the possibilities for one syllable (using just 2 letters for readability). In order to get more syllables, all I could think of was expanding it for each syllable like echo {{,p,t}{a,i},{,p,t}{a,i}{,p,t}{a,i}}
(ie, 'all the one syllable combinations then all the two syllable combinations'). Is there a better way to extend this to n syllables, so that I can type something kinda like echo {,p,t}{a,i}*{1..3}
for all the 1, 2, and 3 syllable expansions(and so on)?
3 Answers
You could do something like this
Bash, 165 bytes
f(){
i=$1
exp=$2
con=$2
printf '{'
while [ "$i" -gt 0 ] ; do
(( i-- ))
printf '%s' "$con,"
con+=$exp
done
printf '}'
echo
}
eval echo "$(f 6 '{,p,t}{a,i}')"
-
-
1
-
1And I honestly think that's one valid way of how solving this kind of problem in bash could be considered — a mental sport, but not something you'd want to see for production usage Oct 2 at 0:17
-
Zsh, 73 bytes
c=('' p t) v=(a i) r=({1..4})
(){echo ${(e)@}} '${(el['$^r'*6][$^c$^v])}'
Unrolling it:
$ c=( '' p t ) v=( a i ) r=( {1..4} )
$ echo $c$v
p ta i
$ echo $^c$^v
a i pa pi ta ti
With $^c
instead of $c
, arrays are expanded a bit like in brace expansion.
$ echo ${(l[12][$^c$^v])}
$^c$^v$^c$^v
We expand nothing (that parameter expansion has no parameter) using the l
eft padding operator, here padding with $^c$^v
strings to a length of 12
(twice the length of $^c$^v
string).
$ echo ${(el[12][$^c$^v])}
aa ai apa api ata ati ia ii ipa ipi ita iti paa pai papa papi pata pati pia pii pipa pipi pita piti taa tai tapa tapi tata tati tia tii tipa tipi tita titi
If we add the e
parameter expansion flag, the expansions in the result are e
valuated/e
xpanded.
So all we need to do is generate those for paddings of 6, 12, ... n*6.
$ echo '${(el['$^r'*6][$^c$^v])}'
${(el[1*6][$^c$^v])} ${(el[2*6][$^c$^v])} ${(el[3*6][$^c$^v])} ${(el[4*6][$^c$^v])}
If we can put those words in an array, we can apply the e
flag to it to expand the result. For that we use an anonymous function, and pass those words as arguments, and they'll be available in the $@
aka $argv
array within.
Usind the most of your code/logic.
ksh, 95 bytes, no evil eval
:)
n=4
for ((i=1; i<=n; i++)) {
printf -v x '{,p,t}{a,i}%.0s' {1..$i}
printf '%s\n' $x
}
If your ksh
implementation don't support printf -v x
, replace by x=$(printf ...)
-
Note that assumes recent versions of ksh93u+m for
printf -v
.-v
is not really necessary in ksh93 since you can dox=${ printf ....;}
instead. Oct 2 at 8:07
python scriptname.py
. No magic involved!