Divertimento con stringhe e numeri


13

Ecco un puzzle di programmazione per te:

Dato un elenco di coppie di stringhe e numeri corrispondenti, ad esempio [[A,37],[B,27],[C,21],[D,11],[E,10],[F,9],[G,3],[H,2]], genera un altro elenco che avrà solo le stringhe nel modo seguente:

  1. Il conteggio totale di qualsiasi stringa deve essere esattamente uguale al suo numero corrispondente nei dati di input.

  2. Nessuna stringa deve essere ripetuta adiacenti nella sequenza e ogni stringa deve apparire nell'elenco di output.

  3. La selezione della stringa successiva dovrebbe essere fatta in modo casuale purché non si infrangano sopra le due regole. Ogni soluzione dovrebbe avere una probabilità diversa da zero di essere scelta.

  4. Se non è possibile alcuna combinazione, l'output dovrebbe essere giusto 0.

L'elenco di input può essere fornito in qualsiasi ordine (ordinato o non ordinato) e le stringhe nell'elenco possono essere di qualsiasi lunghezza.


Output di esempio per l'ingresso di esempio sopra 1

[A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,C,A,C,A,C,A,C,A,C,A,C,A,C,A,C,A,C,A,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,E,F,E,F,E,F,E,F,E,F,E,F,E,F,E,F,E,F,E,G,H,G,H,G]


Ingresso campione 2:

[[A,6],[B,1],[C,1]]

Uscita per secondo ingresso:

0

poiché nessun elenco possibile in base alle regole.


Esempio di input 3:

[[AC,3],[BD,2]]

uscita valida: [AC,BD,AC,BD,AC]

uscita non valida: [AC,BD,AC,AC,BD]


Se sono necessari ulteriori chiarimenti, per favore, non esitate a dirmelo nei commenti e agirò prontamente di conseguenza.

Questo è , quindi vince il codice più breve in byte per ogni lingua!


Bella sfida! Penso che sia un po 'meno specificato dai nostri standard. Consiglio vivamente l'uso di The Sandbox per ricevere molti feedback prima di pubblicare una sfida in modo da non ottenere voti negativi o voti stretti! :-) Non vedo l'ora di vedere altre tue belle sfide!
Giuseppe,

@Giuseppe grazie proverò a farlo. Fammi sapere se devo aggiungere dettagli se mi sono perso in questo.
Stupid_Intern

1
Possiamo prendere 2 input, solo le stringhe e solo i numeri?
FrownyFrog,

ci può essere ambiguità nell'uso della frase 'random', molte di queste soluzioni usano librerie "random" che sono in realtà solo pseudocasuali.
don luminoso

Risposte:


6

Gelatina , 11 byte

Œṙ'Œ!⁻ƝẠ$ƇX

Provalo online!

Œṙ'Œ!⁻ƝẠ$ƇX Arguments: z
  '         Flat: Apply link directly to x, ignoring its left and right depth properties
Œṙ            Run-length decode
   Œ!       Permutations of x
         Ƈ  Filter; keep elements of x for which the link returns a truthy result
        $     ≥2-link monadic chain
      Ɲ         Apply link on overlapping pairs (non-wrapping)
     ⁻            x != y
       Ạ        Check if all elements of x have a truthy value (+vacuous truth)
          X Pick a random element of x; return 0 if the list is empty.

Se Œṙnon vettorializzasse, avrebbe funzionato senza'
dylnan il

5

Gelatina , 17 byte

Wẋ¥Ɲ€ẎẎŒ!Œɠ’SƊÐḟX

Provalo online!


Quando provo ["A", 100], ["B", 3]non produce nulla, è bloccato, penso.
Stupid_Intern

1
@newguy Generare tutte le permutazioni di 103 oggetti non è famoso per la sua velocità. Come riferimento, il risultato dopo Œ!avrà 9902900716486180407546715254581773349090165822114492483005280554699876665841622283214144107388353849265351638597729209322288213441514989158400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Erik the Outgolfer,

@newguy Questa soluzione è O(n!)breve ma la velocità non ha importanza. Non provarlo con qualcosa in cui i numeri si sommano a più di circa 6-8 o giù di lì: P
HyperNeutrino,

Potrebbe Œṙaiutare?
Arnauld,

1
@dylnan Non credo che funzioni con le stringhe con cui ho provato ["AT", 3], ["B", 3]e ottenuto TBATATBABcome output che è sbagliato
Stupid_Intern

5

Python 2 , 114 189 185 174 byte

from random import*
a=input()
s=u=[]
while a:x,y=a.pop(a.index(next((w for w in a if w[1]>sum(v[1]for v in a+u)/2),choice(a))));s=s+[x];a+=u;u=[[x,y-1]]*(y>1)
print[s,0][y>1]

Provalo online!

Ahia! Molto più difficile con la regola 3 ... :). Sto ancora cercando di evitare l' O(n!)approccio, in modo che possa gestire tutti i casi di test prima della morte per calore dell'universo ...

Algoritmo: supponiamo che sia la somma totale dei conteggi delle stringhe t. Se una stringa ha un conteggio ncon 2*n>t+1, allora non è possibile soddisfare i vincoli. Pertanto, se qualsiasi stringa (escludendo quello scelto in precedenza) ha conteggio ncon 2*n=t+1, quindi dobbiamo scegliere quella stringa successiva. Altrimenti, possiamo scegliere a caso qualsiasi stringa che non sia la stringa scelta in precedenza.


1
@Arnauld: completamente perso! riparato ora.
Chas Brown,

4

R , 148 141 byte

function(x,y,p=combinatXXpermn(rep(seq(y),y)),q=which(sapply(lapply(p,diff),all)))"if"(n<-sum(q|1),"if"(n-1,x[p[[sample(q,1)]]],x[p[[q]]]),0)

Provalo online! (Ho copiato combinat::permne chiamato combinatXXpermnlì.)

Forza bruta O (n!) Soluzione.

Utilizza permndal combinatpacchetto per generare tutti i possibili ordini. Quindi controlla se qualcuno segue le regole e ne sceglie una a caso.


n<-sum(n|1)credo sia un byte più breve. Ma la stranezza di sampleun input lungo è piuttosto frustrante qui.
Giuseppe,

anche a golf un po ', provalo qui - ho dovuto rimuovere il combinatXXpermn dall'intestazione per ottenere il link abbastanza piccolo ...
Giuseppe

Ho avuto qualcosa di molto simile prendendo input come frame di dati. Il problema con bruteforce è che non gestirà input troppo grandi ...
JayCe,

@JayCe è anche possibile un algoritmo di forza non bruta, vista la regola 3 di questa sfida?
ngm,

Sono d'accordo che potrebbe non farlo. Sarebbe stato più interessante senza la regola 3.
JayCe,

3

JavaScript, 112 byte

Primo passaggio a questo, più golf per (si spera) seguire.

f=([i,...a],o=[])=>a.sort((x,y)=>(y[1]-x[1])*Math.random()-n*.5,n=--i[1],o.push(i[0]))+a?f(n?[...a,i]:a,o):n?0:o

Provalo online


1
Grazie, @Arnauld, mi ero perso. Avrei dovuto ricontrollare le specifiche piuttosto che seguire ciecamente il vantaggio di Chas. Implementata una soluzione rapida, dovrò tornarci più tardi per vedere se posso giocarci meglio.
Shaggy,

Sì, la terza regola è OK per gli esolang che possono facilmente forzare comunque tutte le soluzioni, ma rende molto più difficile implementare algoritmi più brevi in ​​altre lingue ... BTW: questo ora sembra restituire 0 su voci valide di volta in volta.
Arnauld,

Implementata un'altra soluzione rapida, @Arnauld - se ciò non lo ordina, dovrò eliminare di nuovo fino a quando non avrò più tempo per esaminarlo. Nota: ho preso in considerazione la specifica che la stringa successiva deve essere scelta in modo casuale, il che implica che la prima selezione non deve essere casuale.
Shaggy,

1
@Shaggy - Sono d'accordo, non dovresti mai seguire ciecamente qualsiasi cosa io faccia! :)
Chas Brown,

3

J, 60 53 byte

-7 grazie a FrownyFrog

(?@#{])@(#~*/@(2~:/\])"1)@(]i.@!@#@;A.;) ::0(#~>)/&.>

originale

(?@#{])@(#~2&([:*/~:/\)"1)@(A.~i.@!@#)@;@:(([#~>@])/&.>) ::0

ungolfed

(?@# { ])@(#~ 2&([: */ ~:/\)"1)@(A.~ i.@!@#)@;@:(([ #~ >@])/&.>) ::0

Suggerimenti per il miglioramento sono benvenuti.

Provalo online!


Golfed to 53
FrownyFrog,

fantastico tyvm @FrownyFrog, aggiornerò post più tardi
Giona

oops, [:*/2~:/\|:è due più corto
FrownyFrog

2

JavaScript (ES6), 160 byte

a=>(g=(a,m=[])=>a.map((v,n)=>v==m[0]||g(a.filter(_=>n--),[v,...m]))>[]?0:r=m)(a.reduce((p,[v,n])=>[...p,...Array(n).fill(v)],r=[]).sort(_=>Math.random()-.5))||r

Provalo online!


2

Carbone , 38 byte

WΦθ§κ¹«≔‽Φ∨Φι›⊗§κ¹ΣEι§μ¹ι¬⁼κυυ§υ⁰⊞υ⊖⊟υ

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

WΦθ§κ¹«

Ripetere finché è presente almeno un conteggio diverso da zero.

Φι›⊗§κ¹ΣEι§μ¹

Trova qualsiasi conteggio che costituisce più della metà del resto.

∨...ι

Se non ce n'era uno, prendi semplicemente i conteggi diversi da zero filtrati in precedenza.

Φ...¬⁼κυ

Filtra la stringa che è stata emessa l'ultima volta.

≔‽∨...υ

Assegna un elemento casuale dal primo non vuoto dei due elenchi sopra all'ultima stringa di output. Si noti che se viene inserita una combinazione impossibile, il programma si arresterà in modo anomalo a questo punto.

§υ⁰

Stampa la stringa.

⊞υ⊖⊟υ

Decrementa il suo conteggio.


Questo produce output non validi, come nel tuo esempio con ["h4x0r", 1337]incluso come stringa.
ngm,

@ngm Ho riorganizzato il codice e ora si arresta in modo anomalo se lo fai ... purtroppo la corretta validazione costerà più byte.
Neil,

2

Rubino , 85 byte

L'approccio della forza bruta (grazie a Giona per l'idea).

->l{l.flat_map{|a,b|[a]*b}.permutation.select{|p|r=0;p.all?{|a|a!=r&&r=a}}.sample||0}

Provalo online!

Rubino , 108 100 96 byte

In precedenza, l'approccio Bogosort

->l{w=[];l.map{|a,b|w+=[a]*b;b}.max*2>w.size+1?0:(w.shuffle!until(r='';w.all?{|a|a!=r&&r=a});w)}

Provalo online!


eccone uno per 93: provalo online!
Giona,

2

Ruggine 633 byte

Ciò che rende questo un po 'diverso dagli altri è che è iniziato con l'idea di riorganizzare le stringhe simulando un sistema fisico. Ogni stringa viene prima duplicata il numero appropriato di volte. Quindi ogni singola stringa viene trattata come una particella in uno spazio. Due particelle con lo stesso valore di stringa si "respingono" a vicenda, mentre due particelle con valori diversi si attraggono. Ad esempio, se iniziamo con AAAAAAABBBBCC, gli As si abrogheranno a vicenda, allontanandosi l'uno dall'altro, consentendo ai Bs di spostarsi tra di loro. Nel tempo questo raggiunge una bella miscela di particelle. Dopo ogni iterazione del "movimento delle particelle", il programma verifica che non vi siano particelle uguali adiacenti, quindi si ferma e stampa lo stato del sistema, che è semplicemente l'elenco delle stringhe in ordine, come appaiono nello spazio 1 dimensionale.

Ora, quando si tratta di implementare effettivamente quel sistema fisico, è iniziato come usando la vecchia tecnica demo / gioco per PC fashiond, per memorizzare la posizione e la velocità di ogni particella come numeri, quindi passare attraverso iterazioni per aggiornare posizione e velocità. Ad ogni iterazione, stiamo aggiungendo velocità alla posizione (movimento) e aggiungendo accelerazione alla velocità (variazione della velocità di movimento) e calcolando l'accelerazione (trovando la forza sulla particella). Per semplificare, il sistema non calcola la forza su ciascuna particella in base a tutte le altre particelle, ma controlla solo le particelle immediatamente adiacenti. C'era anche un effetto di "smorzamento" in modo che le particelle non accelerassero troppo e volassero all'infinito (la velocità è ridotta di x percentuale ogni passo, per esempio).

Attraverso il processo del golf, tuttavia, tutto questo è stato ridotto e semplificato drasticamente. Ora, invece di due particelle simili che si respingono, si "teletrasportano" semplicemente. Particelle diverse semplicemente "scuotono" un pochino per prevenire il ristagno nel sistema. Ad esempio se A è vicino ad A si teletrasporterà. Se A è vicino a B, si sposta solo leggermente. Quindi controlla se le condizioni sono soddisfatte (nessuna particella simile adiacente) e stampa le stringhe in ordine, in base alla loro posizione nello spazio 1-d. È quasi più un algoritmo di ordinamento che una simulazione - poi, si potrebbe vedere gli algoritmi di ordinamento come una forma di "deriva" simulata basata su "massa". Io divago.

Comunque, questo è uno dei miei primi programmi Rust, quindi ho rinunciato dopo diverse ore di golf, anche se potrebbero esserci ancora delle opportunità. Il bit di analisi è difficile per me. Legge la stringa di input dall'input standard. Se lo si desidera, potrebbe essere sostituito con "let mut s =" [[A, 3], [B, 2]] ". Ma in questo momento faccio 'echo [[A, 3], [B, 2]] | cargo run "dalla riga di comando.

Il calcolo dell'arresto è un po 'un problema. Come rilevare se uno stato valido del sistema non verrà mai raggiunto? Il primo piano consisteva nel rilevare se lo stato "corrente" avesse mai ripetuto un vecchio stato, ad esempio se ACCC cambia in CACC ma poi di nuovo in ACCC sappiamo che il programma non si chiuderà mai, dato che è solo pseudo-casuale. Dovrebbe quindi rinunciare e stampare 0 se ciò accade. Tuttavia, questo sembrava un'enorme quantità di codice Rust, quindi invece ho appena deciso che se attraversa un numero elevato di iterazioni, è probabilmente bloccato e non raggiungerà mai uno stato stabile, quindi stampa 0 e si ferma. Quanti? Il numero di particelle al quadrato.

Codice:

extern crate regex;
struct P {s:String,x:i32,v:i32}
fn main() {
    let (mut i,mut j,mut p,mut s)=(0,0,Vec::new(),String::new());
    std::io::stdin().read_line(&mut s);
    for c in regex::Regex::new(r"([A-Z]+),(\d+)").unwrap().captures_iter(&s) {
        for _j in 0..c[2].parse().unwrap() {p.push(P{s:c[1].to_string(),x:i,v:0});i+=1;}
    }
    let l=p.len(); while i>1 {
        j+=1;i=1;p.sort_by_key(|k| k.x);
        for m in 0..l {
            let n=(m+1)%l;
            if p[m].s==p[n].s {p[m].v=p[m].x;if n!=0 {i=2}} else {p[m].v=1}
            p[m].x=(p[m].x+p[m].v)%l as i32;
        }
        if j>l*l{p.truncate(1);p[0].s="0".to_string();i=1}
    }
    for k in &p{print!("{}",k.s)};println!();
}

Questo è un modo interessante di pensare a questo problema, mi piace. Quanto bene fa in pratica? Mi sento comel2il limite potrebbe essere troppo basso, che potrebbero esserci troppi falsi negativi in ​​cui l'algoritmo pensa che non ci sia un output valido quando esiste - ma non ho potuto testare quella teoria poiché TIO apparentemente non ha la regexcassa.
Sundar - Ripristina Monica il

ha superato gli esempi che ho alimentato, anche se non l'ho sfocato. l'ho modificato per funzionare in TIO, è necessario modificare 'let s = [("A", 3), ("B", 2), ("ZZ", 4)];' line, bit.ly/2LubonO
don bright

1

JavaScript (Node.js) , 249 byte

l=>(a=[],g=(r,s)=>s.length?s.forEach((x,i)=>g([...r,x],s.filter((y,j)=>j-i))):a.push(r),g([],l.reduce(((a,x)=>[...a, ...(x[0]+' ').repeat(x[1]).split(' ')]),[]).filter(x=>x)),p=a.filter(a=>a.every((x,i)=>x!=a[i+1])),p[~~(Math.random()*p.length)]||0)

Provalo online!


1

Java (JDK 10) , 191 byte

S->N->{var l=new java.util.Stack();int i=0,j;for(var s:S)for(j=N[i++];j-->0;)l.add(s);for(;i>0;){i=0;java.util.Collections.shuffle(l);for(var s:S)if(s.join("",l).contains(s+s))i++;}return l;}

Provalo online!

Questo non ritorna mai se non ci sono soluzioni.

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.