shCoc/NhN/zhNm>o_/zZSzdUz
Uses an all new algorithm, inspired by this answer.
(implicit) z = input()
(implicit) print
s combine list of strings into one string
h first list in
C matrix transpose of (e.g. first characters in first list, etc.)
o order_by(lambda N:
c float_div(
/NhN N.count(N[0]),
/zhN z.count(N[0])),
m map(lambda d:
> slice_head(
o order_by(lambda Z:
_/zZ -1*z.count(Z),
Sz sorted(z)),
d d),
Uz range(len(z))
Step by step:
First, we sorted the characters by their commonness, ties broken alphabetically. This is o_/zZSz
. o
is the same as Python's sorted(<stuff>,key=<stuff>)
, with a lambda expression for the key, except it keeps it as a string.
Then we generate a list of the prefixes of that string, from length len(z)
to length 1. >
is equivalent to python's <stuff>[<int>:]
.
Then, we reorder this list of prefix strings by the fractional location, 0 being the left edge and 1 being the right, of the first character of the prefix on the rectangular layout seen in the question. /NhN
counts how many times the first character in the prefix occurs in the prefix, while /zhN
gives the number of occurrences of the first character in the prefix in the string as a hole. This assigns each prefix being led by each character in a group a different fraction, from 1/k
for the right most occurrence of that character to k/k
for the left most. Reordering the prefix list by this number gives the appropriate position in the layout. Ties are broken using the prior ordering, which was first by count then alphabetical, as desired.
Finally, we need to extract the first character from each prefix string, combine them into a single string, and print them out. Extracting the first characters is hC
. C
performs a matrix transpose on the list, actually zip(*x)
in Python 3. h
extracts the first row of the resultant matrix. This is actually the only row, because the presence of the 1 character prefix prevents any other complete rows from being formed. s
sums the characters in this tuple into a single string. Printing is implicit.
Test:
$ pyth -c 'shCoc/NhN/zhNm>o_/zZSzdUz' <<< 'oroybgrbbyrorypoprr'
rorbyroprbyorrobypg
Incremental program pieces on oroybgrbbyrorypoprr
:
Sub-Piece Output
Sz bbbgoooopprrrrrryyy
o_/zNSz rrrrrroooobbbyyyppg (uses N because o uses N on first use.)
m>o_/zNSzdUz ['rrrrrroooobbbyyyppg', 'rrrrroooobbbyyyppg', 'rrrroooobbbyyyppg', 'rrroooobbbyyyppg', 'rroooobbbyyyppg', 'roooobbbyyyppg', 'oooobbbyyyppg', 'ooobbbyyyppg', 'oobbbyyyppg', 'obbbyyyppg', 'bbbyyyppg', 'bbyyyppg', 'byyyppg', 'yyyppg', 'yyppg', 'yppg', 'ppg', 'pg', 'g']
oc/NhN/zhNm>o_/zZSzdUz ['roooobbbyyyppg', 'obbbyyyppg', 'rroooobbbyyyppg', 'byyyppg', 'yppg', 'rrroooobbbyyyppg', 'oobbbyyyppg', 'pg', 'rrrroooobbbyyyppg', 'bbyyyppg', 'yyppg', 'ooobbbyyyppg', 'rrrrroooobbbyyyppg', 'rrrrrroooobbbyyyppg', 'oooobbbyyyppg', 'bbbyyyppg', 'yyyppg', 'ppg', 'g']
Coc/NhN/zhNm>o_/zZSzdUz [('r', 'o', 'r', 'b', 'y', 'r', 'o', 'p', 'r', 'b', 'y', 'o', 'r', 'r', 'o', 'b', 'y', 'p', 'g')]
shCoc/NhN/zhNm>o_/zZSzdUz rorbyroprbyorrobypg
Old answer:
ssCm*+t*u*G/zHS{-zd1]kd/zdo_/zNS{z
This program works by calculating how many times to replicate a certain sublist. The sub-list looks like ['', '', '', '', ... , 'r']
. The total length of this sub-list is the product of the number of occurrences of all of the other candies, which is u*G/zHS{-zd1
. The full sublist is constructed by replicating the list of the empty string ,]k
, that many times, then removing and element with t
and add the candy name to the end with +d
.
Then, this sub-list is replicated as many times as that candy is found in the input, /zd
, ensuring each candy's list is of equal length.
Now, with this function mapped over all of the unique candies in proper sorted order (o_/zNS{z
), we have a rectangle similar to the one in the question statement, but with empty strings instead of periods. Doing a matrix transpose (C
) followed by two summations (ss
) gives the final string.
Verification:
$ pyth programs/candy.pyth <<< 'oroybgrbbyrorypoprr'
rorbyroprbyorrobypg
r
would place the candy on a 84x6 board \$\endgroup\$