Trova il modello ottimale


33

Data una stringa s composta da lettere minuscole, come ad esempio

aabaaababbbbaaba

e un intero positivo n , come ad esempio 4, genera una stringa di lunghezza n t tale che quando t viene ripetuto per la lunghezza di s , hanno il maggior numero di caratteri in comune possibile. Per l'esempio dato, l'output ottimale sarebbe aaba, poiché ha tredici caratteri in comune con la stringa di destinazione:

s: aabaaababbbbaaba
t: aabaaabaaabaaaba (aaba)
   ^^^^^^^^  ^ ^^^^

e nessun possibile t ha più. Tuttavia, per aaaaaab, ci sono due possibili output: aaaae aaba, che hanno ciascuno 6 caratteri in comune con la stringa di destinazione:

s: aaaaaab
t: aaaaaaaa (aaaa)
   ^^^^^^ 

s: aaaaaab
t: aabaaaba (aaba)
   ^^ ^^^^

O aaaao aabapuò essere emesso, o entrambi se lo desideri. Nota che s non viene mai ripetuto; il trailing ain entrambi i valori ripetuti di t viene semplicemente ignorato.

Casi test

Inputs -> Valid outputs
1 a -> a
1 aa -> a
2 aa -> aa
1 ab -> a b
2 ab -> ab
1 abb -> b
2 abb -> ab bb
2 ababa -> ab
2 abcba -> ab
2 aabbbbb -> bb  (ab is not a valid output here)
3 aababba -> aab abb
3 aababbaa -> aab
3 asdasfadf -> asf
3 asdasfadfsdf -> asf adf
2 abcdefghijklmnopqrstuvwxyzyx -> yx
2 supercalifragilisticexpialidocious -> ic ii
3 supercalifragilisticexpialidocious -> iri ili ioi
4 supercalifragilisticexpialidocious -> scii
5 supercalifragilisticexpialidocious -> iapic
2 eeeebaadbaecaebbbbbebbbbeecacebdccaecadbbbaceebedbbbddadebeddedbcedeaadcabdeccceccaeaadbbaecbbcbcbea -> bb be
10 bbbbacacbcedecdbbbdebdaedcecdabcebddbdcecebbeeaacdebdbebaebcecddadeeedbbdbbaeaaeebbedbeeaeedadeecbcd -> ebbbdbeece ebdbdbeece
20 aabbbaaabaaabaaaabbbbabbbbabbbabbbbbabbaaaababbbaababbbaababaaaabbaaabbaabbbabaaabbabbaaabbaaaaaaaba -> aabbbbaaabbabbbaabba

Regole

  • Si può presumere che l'input sarà sempre una stringa non vuota di lettere minuscole e un numero intero positivo non maggiore della lunghezza della stringa.
  • Puoi prendere gli input in qualsiasi formato standard e in entrambi gli ordini.
  • È possibile generare una singola stringa o più di una sotto forma di un array, separate da newline o spazi, ecc.
  • Il codice deve terminare per ogni test in meno di 1 minuto su qualsiasi computer abbastanza moderno.
  • Questo è , quindi rendi il tuo codice il più breve possibile.

2
Questa sfida è di qualità Zgarb. Bel lavoro!
Martin Ender,

Suppongo che vengano ignorati solo i personaggi finali? Quindi non ti è permesso ignorare i personaggi principali in questo modo: 2 abb -> badove è costruito come (b)[ab]a: il protagonista (b)è ignorato, [ab]sono corrispondenti.
Kevin Cruijssen,

@KevinCruijssen Esatto, lo schema deve iniziare a ripetere all'inizio.
ETHproductions

Risposte:


11

Gelatina , 11 byte

sZµṢŒrUṀṪµ€

Provalo online!

Non mi aspettavo di battere Dennis su questo, quindi ho provato a FGITW (dopo aver provato diverse possibilità; c'è più di un modo per fare 11). Sono venuto più breve, con mia grande sorpresa.

Prende la stringa quindi il conteggio come argomenti della riga di comando. Uscite su stdout.

Spiegazione

sZµṢŒrUṀṪµ€
s            Split {the first input} into {the second input}-sized groups
 Z           Transpose
  µ      µ€  On each of the transposed groups:
   Ṣ           Sort it;
    Œr         Run-length encode it;
      U        Rearrange it to the form {count, letter};
       Ṁ       Take the largest element (i.e. largest count)
        Ṫ      Take the second element of the pair (i.e. just the letter)

Questo utilizza l'intuizione che la lettera in ciascuna posizione del modello deve essere la lettera più comune corrispondente a quella posizione. Siamo in grado di trovare le lettere corrispondenti a un modello particolare mediante la divisione in gruppi di dimensioni del modello e la trasposizione. Il motivo principale per cui questa soluzione è così lunga è che Jelly non sembra avere un modo breve per trovare la modalità di un elenco (ho fatto diversi tentativi, ma sono tutti lunghi almeno sei byte).

Jelly , 10 byte, basata sulla soluzione di @Dennis

⁸ċ$ÞṪ
sZÇ€

Provalo online!

Questa è una combinazione della soluzione di @Dennis e della mia; c'era una modalità a cinque byte in quella soluzione, che ho rubato per questa soluzione. (Avevo già soluzioni basate ⁸ċ, ma non riuscivo a scendere sotto i sei byte; non avevo pensato di usarlo Þ.)

Spiegazione

µ…µ€e Ç€(con la riga precedente) sono lunghi entrambi tre byte (quest'ultimo richiede una nuova riga) ed equivalenti. Normalmente uso il primo, ma il secondo è più flessibile, in quanto consente di menzionare l'argomento.

Questo rende possibile ordinare ( Þ) per il numero di occorrenze in ( ⁸ċ), quindi prendere l'ultimo elemento ( ), per trovare la modalità in soli cinque caratteri.


5
Bel lavoro superando Dennis con la sua lingua! : P
HyperNeutrino,

10

Mathematica, 51 byte

#&@@@Commonest/@(PadRight@Partition[#2,UpTo@#])&

Input e output sono elenchi di caratteri.

Basato anche sulle modalità delle linee di trasposizione. Credo che abbiano chiamato il built-in per la modalità di un elenco Commonest solo per disprezzare i golfisti di codice.


Almeno è un byte più corto di MostCommon...
ETHproductions

7

Python 3, 99, 73 61 byte

-12, grazie a @Rod

lambda s,n:''.join(max(s,key=s[i::n].count)for i in range(n))

Stessa idea, ma riscriverla per eliminare la dichiarazione di importazione.

lambda s,n:''.join(max(s,key=lambda c:s[i::n].count(c))for i in range(n))

Originale

from collections import*
lambda s,n:''.join(Counter(s[i::n]).most_common(1)[0][0]for i in range(n))

Spiegazione:

s[i::n]                  a slice of every nth character of s, starting at position i

Counter(s[i::n])         counts the characters in the slice
  .most_common()         returns a list of (character, count) pairs, sorted by decreasing count
    [0][0]               grabs the letter from the first pair (i.e., the most common letter
      for i in range(n)  repeat for all starting positions

''.join                  combines the most common letters into a single string

puoi passare a python2.7 e rilasciarlo ''.join()per restituire un elenco di stringhe
Rod

@Rod Dropping gli ''.join(...)farebbe restituire un generatore, non sono sicuro che sia consentito l'output.
L3viathan,

@ L3viathan deve essere python2.7 per funzionare, aggiunto all'altro commento
Rod

Puoi scrivere qualche spiegazione su come funziona?
Dead Possum,

2
@Rod Un elenco di stringhe è consentito nella domanda solo se si restituiscono tutte le possibili soluzioni. Questo è quello che ho pensato che significasse.
mbomb007,

5

Python 2, 106

Ora è una risposta diversa! Stavo pensando a una (quasi) linea d'inizio. Ora ancora più breve, in base all'utilizzo di zip da parte di @Rod.

Grazie a @ L3viathan e @Rod per chiarimenti sull'utilizzo di lambdas come risposta

Provalo online

lambda S,N:max(combinations(S,N),key=lambda s:sum(x==y for x,y in zip(S,s*len(S))))
from itertools import*

Spiegazione:

combinations(S,N) crea tutte le combinazioni di lunghezza N dai caratteri di S

max()hanno un argomento keyche utilizza come funzione di input per confrontare gli elementi

lambda s:sum(x==y for x,y in zip(S,s*len(S))) passato come tale funzione

Questa lambda conta il numero di caratteri corrispondenti nell'elenco delle tuple, prodotto da zip(S,s*len(S))

s- una delle combinazioni ed è multiplata per len(S)cui crea una stringa che è garantita più a lungo di S

zipcrea tuple di caratteri per ogni stringa Se s*len(S)ignora tutti i caratteri che non possono essere abbinati (nel caso di una stringa più lunga di un'altra)

Quindi maxsceglie la combinazione, che produce la somma massima


1
non hai bisogno di usare la []comprensione dell'elenco all'interno delle funzioni, inoltre stai usando 1 for ... if <cond>puoi usarlo direttamente <cond> for ...poiché sarà usato su sum, python prenderà Truecome 1e Falsecome0
Rod

@Rod Grazie! Se dovessi spremere di più la mia risposta, si trasformerà nella tua risposta, l'approccio è lo stesso: D Quindi sto provando qualcosa di diverso in questo momento
Dead Possum

Sì, sto solo dicendo che puoi usare le tue risposte future: 3
Rod

1
Il passaggio a un lambda salverà 7 byte.
L3viathan,

1
@DeadPossum Intendeva questo (nota il piè di pagina e l'intestazione) e sì, una funzione è una risposta valida , se è un lambda non hai nemmeno bisogno delf= (a meno che non sia ricorsivo)
Rod

5

JavaScript (ES6), 104 101 94 byte

(n,s)=>s.replace(/./g,(_,i)=>[...s].map((c,j,a)=>j%n-i||(a[c]=-~a[c])>m&&(m++,r=c),m=r=``)&&r)

Salvato 3 byte due volte grazie a @Arnauld. Soluzione a 97 byte che funziona con tutti i caratteri non newline:

(n,s)=>s.replace(/./g,(_,i)=>[...s].map((c,j)=>j%n-i||(o[c]=-~o[c])>m&&(m++,r=c),m=r=``,o={})&&r)

La precedente soluzione da 104 byte funziona anche con i caratteri di nuova riga:

(n,s)=>[...Array(n)].map((_,i)=>[...s].map((c,j)=>j%n-i||(o[c]=-~o[c])>m&&(m++,r=c),m=0,o={})&&r).join``

Molto bella. Ho aggiunto una soluzione come riferimento quando ho aggiunto casi di test e sono arrivato a 122 byte, passando in rassegna tutti i caratteri, salvando i conteggi in una matrice di oggetti, quindi costruendo la stringa da quella matrice.
ETHproductions

Piuttosto che inizializzare osu un nuovo oggetto, potresti semplicemente riutilizzare l'array passato mapusando il suo terzo parametro?
Arnauld,

@Arnauld Hmm, immagino che funzioni perché la domanda garantisce lettere minuscole, quindi non confonderò gli elementi dell'array con i conteggi ...
Neil

Penso che (n,s)=>s.replace(/./g,(_,i)=>i<n?[...s].map((c,j,a)=>j%n-i||(a[c]=-~a[c])>m&&(m++,r=c),m=0)&&r:'')dovrebbe salvare altri 3 byte. (O 4 byte utilizzando la sintassi del curry.)
Arnauld

@Arnauld Non male, ma mi sono rasato altri due byte. (E anche corretto il mio conteggio dei byte; una nuova riga finale li stava gettando via.)
Neil

3

Gelatina , 12 11 byte

s@ZċþZMḢ$€ị

Provalo online!

Come funziona

s@ZċþZMḢ$€ị  Main link. Arguments: n (integer), s (string)

s@           Split swapped; split s into chunks of length n.
  Z          Zip/transpose, grouping characters that correspond to repetitions.
   ċþ        Count table; for each slice in the previous result, and each character
             in s, count the occurrences of the character in the group.
             This groups by character.
     Z       Zip/transpose to group by slice.
        $€   Map the two-link chain to the left over the groups.
      M        Find all maximal indices.
       Ḣ       Head; pick the first.
          ị  Index into s to retrieve the corresponding characters.

Jelly ha commenti?
caird coinheringaahing

No non lo fa.
Dennis,

2

Pyth, 11 byte

meo/dNd.TcF

Accetta input s,ne output come un elenco di caratteri.

Spiegazione

meo/dNd.TcF
         cFQ   Split s into chunks of length n.
       .T      Transpose.
m o/dNd        Sort characters in each string by frequency.
 e             Take the most common.

2

Japt , 16 15 byte

Salvato 1 byte grazie a @obarakon

Ç=VëUZ)¬ñ!èZ o

14 byte di codice + 1 byte per il -Pflag. Provalo online!

Ungolfed e spiegazione

 Ç   =VëUZ)¬ ñ!èZ o
UoZ{Z=VëUZ)q ñ!èZ o}
                          Implicit: U = input number, V = input string
Uo                        Create the range [0...U).
  Z{               }      Map each item Z by this function:
      VëUZ                  Take every U'th char of V, starting at index Z.
    Z=    )                 Call the result Z.
           q                Split the result into chars.
             ñ!èZ           Sort each char X by the number of occurrences of X in Z.
                  o         Pop; grab the last item (the most common char).
                      -P  Join the results (array of most common chars) into a string.

Penso che puoi sostituirlo gJcono
Oliver

@obarakon È geniale, grazie!
ETHproductions

1

Python 2 , 132 byte

from itertools import*
p,k=input()
b=l=len(p)
for i in combinations(p,k):
 x=sum(x!=y for x,y in zip(p,i*l))
 if x<b:b,o=x,i
print o

Provalo online!


1

05AB1E , 17 byte

Iôð«øvy{.¡é®èÙJðÜ

Provalo online!

Spiegazione

Iô                 # split 2nd input in chunks of 1st input size
  ð«               # append a space to each
    ø              # zip
     vy            # for each y in the zipped list
       {           # sort the string
        .¡         # group into chunks of consecutive equal elements
          é        # sort by length
           ®è      # pop the last element (the longest)
             Ù     # remove duplicate characters from the string
              J    # join the stack into one string
               ðÜ  # remove any trailing spaces

1

PHP, 245 byte

function p($c,$s,$r=""){global$a;if(($c-strlen($r)))foreach(str_split(count_chars($s,3))as$l)p($c,$s,$r.$l);else{for($v=str_pad("",$w=strlen($s),$r);$z<$w;)$t+=$v[$z]==$s[$z++];$a[$t][]=$r;}}p($argv[1],$argv[2]);ksort($a);echo join(" ",end($a));

Versione online

Abbattersi

function p($c,$s,$r=""){
    global$a;
    if(($c-strlen($r)))  # make permutation
        foreach(str_split(count_chars($s,3))as$l)
            p($c,$s,$r.$l); #recursive
    else{
        for($v=str_pad("",$w=strlen($s),$r);$z<$w;) 
        $t+=$v[$z]==$s[$z++]; #compare strings
        $a[$t][]=$r; # insert value in array
    }
}
p($argv[1],$argv[2]); #start function with the input parameter
ksort($a); # sort result array 
echo join(" ",end($a)); #Output

1

Haskell, 84 byte

import Data.Lists
f n=map(argmax=<<(length.).flip(filter.(==))).transpose.chunksOf n

Esempio di utilizzo:

f 10 "bbbbacacbcedecdbbbdebdaedcecdabcebddbdcecebbeeaacdebdbebaebcecddadeeedbbdbbaeaaeebbedbeeaeedadeecbcd"
"ebbbdbeece"

Dividi la stringa di input in blocchi di lunghezza n, trasponi e trova per ogni sotto-elenco l'elemento più frequente.


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.