Mangiare caramelle nell'ordine corretto


36

Quando si tratta di mangiare caramelle, mi tengo a standard più elevati rispetto al tipico laico. Esiste un delicato equilibrio tra "confonderlo" e "salvare il meglio per ultimo".

In questa sfida, ti verrà data una serie di personaggi in cui ogni personaggio rappresenta un pezzo di caramelle. Personaggi diversi (sensibili al maiuscolo / minuscolo) rappresentano diversi tipi di caramelle. Il programma deve quindi determinare l'ordine corretto del consumo di caramelle, in base alla procedura seguente. È possibile scrivere un programma completo (STDIN / STDOUT) o una funzione denominata per eseguire questa attività.

Diciamo che la mia scorta di caramelle è oroybgrbbyrorypoprr. In primo luogo, ordino le caramelle in pile dello stesso tipo, con maggiori quantità nella parte superiore, usando valori di caratteri ASCII più bassi come tie-breaker.

rrrrrr
oooo
bbb
yyy
pp
g

Quindi prendo ogni fila di caramelle e le dispongo ugualmente lungo un intervallo. Ad esempio, se ci sono 3 pezzi di caramelle, uno viene posizionato 1/3 del percorso, 2/3 del percorso e alla fine.

.r.r.r.r.r.r
..o..o..o..o
...b...b...b
...y...y...y
.....p.....p
...........g

Poi, scendo ogni colonna per creare il mio ordine caramelle finale, rorbyroprbyorrobypg.

Ingresso

Una stringa che contiene la scorta di caramelle. L'input per l'esempio sopra avrebbe potuto essere:

oroybgrbbyrorypoprr

Produzione

Una stringa contenente le caramelle è stata riorganizzata nell'ordine corretto di consumo.

rorbyroprbyorrobypg

punteggio

Questo è il codice golf. Vince la risposta più breve in byte. Si applicano le regole standard del code-golf.


Aggiungete solo uno spazio più grande se i numeri delle caramelle sono irregolari? Diciamo in questo caso se avessi un'altra caramella come sarebbe la griglia?
Vajura,

38
Finalmente qualcuno che sa come mangiare le caramelle.
Michael M.,

12
Quindi ... fondamentalmente caramelle dithering.
COTO

9
Questo in realtà si avvicina molto a come mangio le mie caramelle. :)
Emil,

3
Quanto può essere avida una persona? Esiste un limite al numero di caramelle da mangiare?
Alchymist,

Risposte:


12

CJam, 78 68 61 45 42 39 31 30 byte

l$:L{L\/,~}${:DM+:MD/,LD/,d/}$

Accetta la stringa di input tramite STDIN

Ispirato dall'approccio ricorsivo, ma un po 'diverso. Non c'è bisogno di trasporre o rettangolo affatto !.

Come funziona:

l$:L                              "Sort the input line and store it in L";
    {     }$                      "Sort the string based on this code block output";
     L\/,~                        "Sort based on number of occurrences of each";
                                  "character in the full string";
            {               }$    "Sort the sorted string again";
             :DM+:M               "Store each character in D, add to M and update M";
                   D/,            "Count occurrences of D in M";
                      LD/,        "Count occurrences of D in L";
                          d/      "Sort string based on the ratio of two occurrences";

(Triste che CJam non possa più completare con Pyth a causa della necessità di così tanto gonfiore quanto sintassi)

Provalo qui


4
Non penso che tu abbia bisogno dell'LCM; qualsiasi multiplo dovrebbe funzionare. Ciò dovrebbe consentirti di sostituirlo {_@_@{_@\%}h;/*}con :.
Dennis,

<facepalm> non ci ha pensato.
Ottimizzatore

Congratulazioni per aver dimezzato la tua lunghezza!
isaacg,

Sento il sarcasmo in questo: D
Ottimizzatore

11

Pyth , 25

shCoc/NhN/zhNm>o_/zZSzdUz

Utilizza un algoritmo tutto nuovo, ispirato a questa risposta .

(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))

Passo dopo passo:

  1. Innanzitutto, abbiamo ordinato i personaggi in base alla loro comunanza, i legami spezzati in ordine alfabetico. Questo è o_/zZSz. oè uguale a quello di Python sorted(<stuff>,key=<stuff>), con un'espressione lambda per la chiave, tranne per il fatto che la mantiene come una stringa.

  2. Quindi generiamo un elenco dei prefissi di quella stringa, da lunghezza len(z)a lunghezza 1. >è equivalente a quello di Python <stuff>[<int>:].

  3. Quindi, riordiniamo questo elenco di stringhe di prefisso in base alla posizione frazionaria, 0 essendo il bordo sinistro e 1 essendo la destra, del primo carattere del prefisso sul layout rettangolare visto nella domanda. /NhNconta quante volte il primo carattere nel prefisso si presenta nel prefisso, mentre /zhNfornisce il numero di occorrenze del primo carattere nel prefisso nella stringa come un buco. Questo assegna a ciascun prefisso guidato da ciascun personaggio di un gruppo una frazione diversa, dalla 1/kpiù occorrenza destra di quel personaggio alla k/kpiù sinistra. Riordinando l'elenco dei prefissi con questo numero si ottiene la posizione appropriata nel layout. I legami vengono spezzati usando l'ordinamento precedente, che era prima per conteggio quindi in ordine alfabetico, come desiderato.

  4. Infine, dobbiamo estrarre il primo carattere da ciascuna stringa di prefisso, combinarli in un'unica stringa e stamparli. L'estrazione dei primi caratteri è hC. Cesegue una trasposizione matrice nell'elenco, in realtà zip(*x)in Python 3. hestrae la prima riga della matrice risultante. Questa è in realtà l'unica riga, perché la presenza del prefisso di 1 carattere impedisce la formazione di altre righe complete. ssomma i caratteri di questa tupla in un'unica stringa. La stampa è implicita.

Test:

$ pyth -c 'shCoc/NhN/zhNm>o_/zZSzdUz' <<< 'oroybgrbbyrorypoprr'
rorbyroprbyorrobypg

Programmi incrementali su 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

Vecchia risposta:

Pyth , 34

ssCm*+t*u*G/zHS{-zd1]kd/zdo_/zNS{z

Questo programma funziona calcolando quante volte replicare un determinato elenco secondario. L'elenco secondario appare come ['', '', '', '', ... , 'r']. La lunghezza totale di questo elenco secondario è il prodotto del numero di occorrenze di tutte le altre caramelle, ovvero u*G/zHS{-zd1. L'elenco completo completo viene creato replicando l'elenco della stringa vuota ]k, che molte volte, quindi rimuovendo ed elemento con te aggiungendo il nome della caramella alla fine con +d.

Quindi, questo elenco secondario viene replicato tutte le volte che viene trovata la caramella nell'input /zd, garantendo che l'elenco di ogni caramella abbia la stessa lunghezza.

Ora, con questa funzione mappata su tutte le caramelle uniche nell'ordine corretto ( o_/zNS{z), abbiamo un rettangolo simile a quello nell'istruzione della domanda, ma con stringhe vuote anziché punti. Eseguendo una matrice transpose ( C) seguita da due sommazioni ( ss) fornisce la stringa finale.

Verifica:

$ pyth programs/candy.pyth <<< 'oroybgrbbyrorypoprr'
rorbyroprbyorrobypg

4
Sembra che Pyth supporti la crittografia nella stessa sintassi del linguaggio!
Ottimizzatore

Crittografia @Optimizer? Di cosa stai parlando?
isaacg,

Bello! Probabilmente non avrei mai pensato di cambiare il ciclo for in una mappa. Molto più pulito.
FryAmTheEggman,

Guarda il codice sorgente. Sembra un messaggio crittografato.
Ottimizzatore

2
Puoi fornire un esempio passo passo dell'ultimo algoritmo? Abbastanza per favore :)
Ottimizzatore

6

Perl 5 - 62

61 codice + 1 bandiera.

#!perl -n
print map/(.$)/,sort map/(.$)/*$_/$$1.~$_.$1,map++$$_.$_,/./g

Dividi innanzitutto l'input in un array di caratteri - /./g.

Aggiungi l'indice di occorrenza a ciascuna lettera lasciando i conteggi nelle variabili $a.. $zcon map++$$_.$_. Ora l'array è:

1o
1r
2o
1y
1b
1g
2r
2b
3b
2y
3r
3o
4r
3y
1p
4o
2p
5r
6r

Quindi convertilo in un tasto di ordinamento concatenando: rapporto $_/$$1, conteggio tie breaker ~$_e ASCII valore tie breaker $_. Ciò si tradurrà in (qui con spazi aggiunti per maggiore chiarezza).

0.25 18446744073709551614 o
0.166666666666667 18446744073709551614 r
0.5 18446744073709551613 o
0.333333333333333 18446744073709551614 y
0.333333333333333 18446744073709551614 b
1 18446744073709551614 g
0.333333333333333 18446744073709551613 r
0.666666666666667 18446744073709551613 b
1 18446744073709551612 b
0.666666666666667 18446744073709551613 y
0.5 18446744073709551612 r
0.75 18446744073709551612 o
0.666666666666667 18446744073709551611 r
1 18446744073709551612 y
0.5 18446744073709551614 p
1 18446744073709551611 o
1 18446744073709551613 p
0.833333333333333 18446744073709551610 r
1 18446744073709551609 r

Questo può essere ordinato in base all'ordine lessicografico (predefinito). Alla fine estrai l'ultimo carattere e stampa:print map/(.$)/


5

Python 3.x - 124 byte

C=input()
print("".join(s[1]for s in sorted(enumerate(C),key=lambda
t:((C[:t[0]].count(t[1])+1+1e-10)/C.count(t[1]),t[1]))))

Questo è un algoritmo molto più interessante del metodo rettangolo!
isaacg,

4

Mathematica, 123 119 118 byte

f=FromCharacterCode[s=SortBy;#&@@@s[Join@@(s[Tally@ToCharacterCode@#,-Last@#&]/.{x_,n_}:>({x,#/n}&~Array~n)),{Last}]]&

Definisce una funzione con nome f. Ungolfed:

f = FromCharacterCode[
   s = SortBy;
   # & @@@ s[
     Join @@ (
       s[
         Tally@ToCharacterCode@#,
         -Last@# &
         ] /. {x_, n_} :> ({x, #/n} &~Array~n)
       ),
     {Last}
     ]
   ] &

L'uso di tipi razionali integrati sembrava una buona idea per questo. Ovviamente, questo non è vicino a CJam. Fondamentalmente, sto rappresentando la griglia mostrata nella sfida come un elenco di coppie. La prima cosa nella coppia è il codice carattere, la seconda è la sua posizione come frazione inferiore o uguale a 1 (la colonna finale è 1). Avendo fatto in modo che i singoli personaggi siano già nel giusto ordine, ho solo bisogno di ordinarlo stabilmente per detta frazione per ottenere il risultato desiderato.


3

Pyth 45 47 48 51

Questo potrebbe quasi certamente essere ulteriormente risolto;)

Ko_/zNS{zFGK~Y]*+*t/u*GHm/zdK1/zG]k]G/zG)ssCY

Funziona costruendo un elenco di elenchi, in cui ogni elenco interno è una riga di stringhe vuote e il nome della caramella. Questa lista viene trasposta e quindi le liste interne vengono unite seguite da queste liste unite.

Grazie @isaacg per avermi ricordato la somma!


2
ssu un elenco di stringhe funziona come j"".
isaacg,

3

APL: 38

v⌷⍨⊂⍋⌽(n/-n),⍪∊+\¨n⍴¨÷n←{≢⍵}⌸v←{⍵[⍋⍵]}

Spiegazione:

v←{⍵[⍋⍵]}    orders input string
n←{≢⍵}⌸v     counts how many times each element appears in v
∊+\¨n⍴¨÷n     makes incremental sums in each letter "group" 
⍋⌽(n/-n),⍪   appends number of elements in letter group and orders the obtained matrix
v⌷⍨⊂         orders vector v with computed indices

Può essere testato su tryapl.org


2

R - 166 caratteri

library("plyr");s=function(a){l=table(strsplit(a,s="")[[1]]);l=ldply(l[order(-l,names(l))],function(n)data.frame(seq_len(n)/n));paste(l[order(l[[2]]),1],collapse="")}

versione non golfata

library("plyr")
s <- function(a) {
    tbl <- table(strsplit(a, split = "")[[1]])
    tbl <- tbl[order(-tbl, names(tbl))]
    tbl <- ldply(tbl, function(n) {data.frame(seq_len(n)/n)})
    paste(tbl[order(tbl[[2]]),1], collapse = "")
}

Spiegazione:

  • Dividi in singoli personaggi
  • Tabulare il numero di ogni personaggio
  • Ordinare la tabella in più frequente e quindi in ordine lessicale
  • Posizioni dell'indice per la selezione a 1 / n, 2 / n, 3 / n, ... n-1 / n, 1 dove n è il numero di caramelle
  • Ordina i nomi delle caramelle per indice (order è stabile nell'ordinamento, quindi manterrà l'ordine di denominazione più frequente / lessicale quando un pareggio nell'indice, particolarmente importante con le ultime caramelle)
  • Concatena i nomi delle caramelle insieme per creare la stringa di output

La natura matriciale del problema mi ha fatto pensare che R potesse avere un'idea, ma la migliore interpretazione letterale dell'algoritmo che ho potuto fare era 211 caratteri:

l=function(a){l=table(strsplit(a,s="")[[1]]);l=l[order(-l,names(l))];o=Reduce(`*`,l);m=matrix("",nc=o,nr=length(l));for(r in seq_along(l)){x=l[r];for(c in seq_len(x)*o/x){m[r,c]<-names(x)}};paste(m,collapse="")}

ungolfed:

l <- function(a) {
    tbl <- table(strsplit(a, split = "")[[1]])
    tbl <- tbl[order(-tbl, names(tbl))]
    o <- Reduce(`*`, tbl)
    m <- matrix("", ncol = o, nrow = length(tbl))
    for (r in seq_along(tbl)) {
        for (c in seq_len(tbl[r])*o/tbl[r]) {
            m[r,c] <- names(tbl[r])
        }
    }
    paste(m, collapse="")
}

2

Pyth, 29 byte

Questa è una traduzione diretta della mia risposta CJam in Pyth

oc/|$Y.append(N)$YN/zNo_/zZSz

Provalo online qui


C'è una storia piuttosto lunga dietro questa soluzione e @isaacg mi ha aiutato molto nella comprensione di questo nuovo linguaggio.

Idealmente questa è l'esatta traduzione da parola a parola del mio codice CJam ( 17 byte ):

oc/~kNN/zNo_/zZSz

che significa:

o         order_by(lambda N:
 c                 div(
  /                    count(
   ~kN                       k+=N,                #Update k (initially ""), add N
   N                         N),                  #Count N in updated k
  /zN                  count(z, N)),
 o                 order_by(lambda Z:
  _                         neg(
   /zZ                          count(z, Z)),
  Sz                        sorted(z)))

Ma purtroppo Python non restituisce nulla in a += chiamata, quindi non era un codice Python valido, quindi anche un codice Pyth non valido come in Pyth, un lambda può essere solo un'istruzione return.

Quindi ho esaminato vari metodi e alla fine ho scoperto che Python list.appendrestituisce un Nonevalore, che posso usare. Rendere il codice ( 19 byte ):

oc/|aYNYN/zNo_/zZSz

che significa:

o         order_by(lambda N:
 c                 div(
  /                    count(
   |aYN                      (Y.append(N) or
    Y                         Y)                 #Update Y (initially []), append N
   N                         N),                 #Count N in updated Y
  /zN                  count(z, N)),
 o                 order_by(lambda Z:
  _                         neg(
   /zZ                          count(z, Z)),
  Sz                        sorted(z)))

Ma purtroppo, il supporto di a(append) è stato rimosso da Pyth e la versione che ha il supporto, non ha il supporto per o.

Aggiornamento: il asupporto è stato aggiunto in Pyth ora, quindi il codice di 19 byte sopra funzionerà nel compilatore online. Ma dal momento che questa è una nuova funzionalità che è stata aggiunta dopo l'OP, non la sto inserendo come punteggio e lasciando che il codice a 29 byte sia la mia soluzione.

Quindi ho dovuto fare affidamento su Python grezzo in quel caso, rendendo il codice

o         order_by(lambda N:
 c                 div(
  /                    count(
   |$Y.append(N)$            (Y.append(N) or
    Y                         Y)                 #Update Y (initially []), append N
   N                         N),                 #Count N in updated Y
  /zN                  count(z, N)),
 o                 order_by(lambda Z:
  _                         neg(
   /zZ                          count(z, Z)),
  Sz                        sorted(z)))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.