Diversão com cordas e números

13

Aqui está um quebra-cabeça de programação para você:

Dada uma lista de pares de cadeias e números correspondentes, por exemplo [[A,37],[B,27],[C,21],[D,11],[E,10],[F,9],[G,3],[H,2]], produza outra lista que terá apenas as cadeias da seguinte maneira:

  1. A contagem total de qualquer sequência deve ser exatamente igual ao seu número correspondente nos dados de entrada.

  2. Nenhuma sequência deve ser repetida adjacentemente na sequência e cada sequência deve aparecer na lista de saída.

  3. A seleção da próxima string deve ser feita aleatoriamente, desde que não quebrem acima de duas regras. Cada solução deve ter uma probabilidade diferente de zero de ser escolhida.

  4. Se nenhuma combinação for possível, a saída deve ser justa 0.

A lista de entrada pode ser fornecida em qualquer ordem (classificada ou não) e as seqüências de caracteres na lista podem ter qualquer comprimento.


Saída de amostra para a entrada de amostra acima 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]


Amostra de entrada 2:

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

Saída para segunda entrada:

0

pois nenhuma lista é possível com base em regras.


Entrada de amostra 3:

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

saída válida: [AC,BD,AC,BD,AC]

saída inválida: [AC,BD,AC,AC,BD]


Se mais esclarecimentos forem necessários, não hesite em me informar nos comentários e eu agirei prontamente.

Isso é , então o código mais curto em bytes para cada idioma vence!

Stupid_Intern
fonte
Bom desafio! Eu acho que é um pouco subespecificado pelos nossos padrões. Eu recomendo o uso do Sandbox para obter muitos comentários antes de postar um desafio, para que você não receba votos negativos ou votos próximos! :-) Estou ansioso para ver mais bons desafios de você!
Giuseppe
@ Giuseppe obrigado Vou tentar passar por isso. Informe-me se precisar adicionar mais detalhes, caso tenha esquecido este.
Stupid_Intern
1
Podemos pegar 2 entradas, apenas as strings e apenas os números?
FrownyFrog
pode haver ambiguidade no uso da frase 'aleatório', várias dessas soluções estão usando bibliotecas "aleatórias" que, na verdade, são apenas pseudo-aleatórias.
don bright

Respostas:

6

Gelatina , 11 bytes

Œṙ'Œ!⁻ƝẠ$ƇX

Experimente 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.
Erik, o Outgolfer
fonte
Se Œṙnão vetorizá-lo, funcionaria sem'
dylnan
5

Gelatina , 17 bytes

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

Experimente online!

HyperNeutrino
fonte
Quando tento ["A", 100], ["B", 3], não gera nada que esteja preso, eu acho.
Stupid_Intern
1
@newguy A geração de todas as permutações de 103 itens não é famosa por sua velocidade. Para referência, o resultado depois Œ!terá 99029007164861804075467152545817733490901658221144924830052805546998766658416222832141441073883538492653516385977292093222882134415149891584000000000000000000000000.
Erik the Outgolfer
@ newguy Esta solução é O(n!)curta, mas a velocidade não importa. Não tente com nada em que os números
totalizem
Poderia Œṙajudar?
Arnauld
1
@dylnan Eu não acho que ele está trabalhando para cordas Eu tentei com ["AT", 3], ["B", 3]e tem TBATATBABcomo saída o que é errado
Stupid_Intern
5

Python 2 , 114 189 185 174 bytes

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]

Experimente online!

Ai! Muito mais difícil com a regra 3 ... :). Ainda tentando evitar a O(n!)abordagem, ele pode lidar com todos os casos de teste algum tempo antes da morte pelo calor do universo ...

Algoritmo: suponha que a soma total da contagem de cadeias seja t. Se qualquer cadeia tem uma contagem ncom 2*n>t+1, então não é possível satisfazer as restrições. Portanto, se qualquer cadeia (excluindo o previamente escolhido) tem contagem ncom 2*n=t+1, então devemos escolher essa seqüência seguinte. Caso contrário, podemos escolher aleatoriamente qualquer string que não seja a string escolhida anteriormente.

Chas Brown
fonte
1
@ Arnauld: perdi completamente isso! corrigido agora.
Chas Brown
4

R , 148 141 bytes

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)

Experimente online! (Eu copiei combinat::permne chamei combinatXXpermnlá.)

Solução de força bruta O (n!).

Usa permndo combinatpacote para gerar todos os pedidos possíveis. Em seguida, verifica se alguma delas segue as regras e escolhe uma delas aleatoriamente.

ngm
fonte
n<-sum(n|1)é um byte mais curto, acredito. Mas a peculiaridade de sampleuma entrada de comprimento um é bastante frustrante aqui.
Giuseppe
golfed um pouco mais baixo, bem como, experimentá-lo aqui - Eu tinha que remover o combinatXXpermn do cabeçalho para obter o pequeno o suficiente link ...
Giuseppe
Eu tinha algo muito semelhante recebendo entrada como um dataframe. O problema com bruteforce é que não vai lidar com entradas que são grandes demais ...
Jayce
@ JayCe é possível um algoritmo de força não bruta, dada a regra 3 deste desafio?
ngm
Eu concordo que não. Teria sido mais interessante sem regra 3.
Jayce
3

JavaScript, 112 bytes

Primeiro passe para isso, mais golfe para (espero) a seguir.

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

Experimente online

Shaggy
fonte
1
Obrigado, @Arnauld, eu senti falta disso. Deveria ter checado as especificações ao invés de seguir cegamente a liderança de Chas. Implementada uma solução rápida, terá que voltar mais tarde para ver se consigo jogar melhor.
Shaggy
Sim, a terceira regra é válida para esolangs que podem facilmente forçar todas as soluções, mas torna muito mais difícil implementar algoritmos mais curtos em outros idiomas ... BTW: isso agora parece retornar 0 em entradas válidas de tempos em tempos.
Arnauld
Implementou outra solução rápida, @Arnauld - se isso não resolver, terei que excluir novamente até ter mais tempo para analisá-la. Nota: Acreditamos na especificação de que a próxima sequência precisa ser escolhida aleatoriamente, o que implica que a primeira seleção não precisa ser aleatória.
Shaggy
1
@ Shagy - Eu concordo, você nunca deve seguir cegamente o que eu faço! :)
Chas Brown
3

J, 60 53 bytes

-7 graças a FrownyFrog

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

original

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

destroçado

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

Sugestões para melhorias são bem-vindas.

Experimente online!

Jonah
fonte
Golfed to 53
FrownyFrog
incrível @FrownyFrog tyvm, eu vou atualizar post mais tarde
Jonah
oops, [:*/2~:/\|:é dois mais curto
FrownyFrog
2

JavaScript (ES6), 160 bytes

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

Experimente online!

Arnauld
fonte
2

Carvão , 38 bytes

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

Experimente online! Link é a versão detalhada do código. Explicação:

WΦθ§κ¹«

Repita enquanto houver pelo menos uma contagem diferente de zero.

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

Encontre qualquer contagem que compõe mais da metade do restante.

∨...ι

Se não houver, faça as contagens diferentes de zero filtradas anteriormente.

Φ...¬⁼κυ

Filtre a string que foi exibida na última vez.

≔‽∨...υ

Atribua um elemento aleatório do primeiro não vazio das duas listas acima à última cadeia de saída. Observe que, se uma combinação impossível for inserida, o programa falhará neste momento.

§υ⁰

Imprima a sequência.

⊞υ⊖⊟υ

Reduza sua contagem.

Neil
fonte
Isso produz resultados inválidos, como no seu exemplo, com ["h4x0r", 1337]incluído como uma sequência.
ngm
@ngm Eu reorganizei o código e agora falha se você fizer isso ... a validação adequada vai custar mais bytes, infelizmente.
214 Neil
2

Rubi , 85 bytes

A abordagem da força bruta (obrigado Jonah pela ideia).

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

Experimente online!

Ruby , 108 100 96 bytes

Anteriormente, a abordagem 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)}

Experimente online!

GB
fonte
aqui está um para 93: Experimente online!
Jonah
2

Ferrugem 633 bytes

O que torna isso um pouco diferente dos outros é que ele começou com a idéia de reorganizar as strings simulando um sistema físico. Cada sequência é duplicada primeiro o número apropriado de vezes. Cada sequência individual é tratada como uma partícula em um espaço. Duas partículas com o mesmo valor de cadeia "se repelem", enquanto duas partículas com valores diferentes se atraem. Por exemplo, se começarmos com AAAAAAABBBBCC, o As se revogará, afastando-se um do outro, permitindo que os Bs se movam entre eles. Com o tempo, isso atinge uma boa mistura de partículas. Após cada iteração de 'movimento de partículas', o programa verifica se nenhuma mesma partícula é adjacente, para e imprime o estado do sistema, que é simplesmente a lista de seqüências de caracteres em ordem, como elas aparecem no espaço unidimensional.

Agora, quando se trata de realmente implementar esse sistema físico, ele começou a usar a antiga técnica de jogo / demo para PC, para armazenar cada posição e velocidade de partículas como números, e depois passar por iterações para atualizar a posição e a velocidade. Em cada iteração, estamos adicionando velocidade à posição (movimento) e adicionando aceleração à velocidade (mudança na taxa de movimento) e calculando a aceleração (encontrando a força na partícula). Para simplificar, o sistema não calcula a força em cada partícula com base em todas as outras partículas - apenas verifica as partículas imediatamente adjacentes. Havia também um efeito de 'amortecimento' para que as partículas não acelerassem demais e voassem até o infinito (a velocidade é reduzida em x porcentagem a cada passo, por exemplo).

Através do processo de golfe, no entanto, tudo isso foi reduzido e simplificado drasticamente. Agora, em vez de duas partículas iguais se repelirem, elas simplesmente 'se teletransportam'. Partículas diferentes simplesmente "escorregam" um pouquinho para evitar estagnação no sistema. Por exemplo, se A estiver próximo a A, ele será teleportado. Se A estiver ao lado de B, ele mudará apenas ligeiramente. Em seguida, verifica se as condições são atendidas (sem partículas adjacentes) e imprime as seqüências de caracteres em ordem, com base em sua posição no espaço 1-d. É quase mais um algoritmo de classificação do que uma simulação - então, novamente, é possível ver os algoritmos de classificação como uma forma de 'desvio' simulado com base na 'massa'. Eu discordo.

De qualquer forma, este é um dos meus primeiros programas de ferrugem, então desisti após várias horas de golfe, embora ainda haja oportunidades lá. A parte de análise é difícil para mim. Ele lê a sequência de entrada da entrada padrão. Se desejado, isso poderia ser substituído por "let mut s =" [[A, 3], [B, 2]] ". Mas agora eu echo [[A, 3], [B, 2]] | carga executada 'na linha de comando.

O cálculo da parada é um pouco problemático. Como detectar se um estado válido do sistema nunca será alcançado? O primeiro plano era detectar se o estado 'atual' repetiu um estado antigo, por exemplo, se o ACCC mudar para CACC, mas depois voltar para o ACCC, sabemos que o programa nunca será encerrado, pois é apenas pseudo-aleatório. Ele deve desistir e imprimir 0, se isso aconteceu. No entanto, isso parecia uma quantidade enorme de código Rust, então, em vez disso, decidi que, se passar por um grande número de iterações, provavelmente ficará travado e nunca chegará a um estado estável; portanto, imprime 0 e para. Quantos? O número de partículas ao quadrado.

Código:

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!();
}
não brilhante
fonte
eu2regex
passou nos exemplos que eu a alimentei, embora eu não a confundisse. Eu o modifiquei para funcionar no TIO, você precisa modificar o 'let s = [("A", 3), ("B", 2), ("ZZ", 4)];' linha, bit.ly/2LubonO
don brilhante
1

JavaScript (Node.js) , 249 bytes

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)

Experimente online!

WaffleCohn
fonte
1

Java (JDK 10) , 191 bytes

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;}

Experimente online!

Isso nunca retorna se não houver soluções.

Olivier Grégoire
fonte