Fluxo de letras para palavras

8

Dada uma sequência que contém apenas letras (sem distinção entre maiúsculas e minúsculas), divida-a em palavras de comprimentos uniformemente aleatórios, usando a distribuição abaixo, com exceção da última palavra, que pode ter qualquer comprimento válido (1-10). Sua saída são essas palavras, como uma sequência separada por espaço ( "test te tests"), uma matriz de sequências ( ["test","te","tests"]) ou qualquer outro formato de saída semelhante.

Distribuição do comprimento da palavra

Word Length - Fractional Chance / 72 - Rounded Percentage
1 - 2 / 72 - 2.78%
2 - 14 / 72 - 19.44%
3 - 16 / 72 - 22.22%
4 - 12 / 72 - 16.67%
5 - 8 / 72 - 11.11%
6 - 6 / 72 - 8.33%
7 - 5 / 72 - 6.94%
8 - 4 / 72 - 5.56%
9 - 3 / 72 - 4.17%
10 - 2 / 72 - 2.78%

Suas probabilidades não precisam corresponder exatamente - elas podem ser desativadas por 1/144th ou .69%, em qualquer direção (mas obviamente elas ainda devem somar 72/72ou 100%).

Os dados foram adivinhados a partir da quarta página, primeira figura deste artigo .

Casos de teste com saída de amostra

O comportamento em casos de teste muito curtos (comprimento <11) é indefinido.

Observe que eu os criei manualmente, para que eles sigam ou não a distribuição uniforme acima.

abcdefghijklmnopqrstuvwxyz
abcd efgh i jklmnopq rs tu vwx yz

thequickbrownfoxjumpedoverthelazydog
t heq uick brown fo xj ump edo vert helazydog

ascuyoiuawerknbadhcviuahsiduferbfalskdjhvlkcjhaiusdyfajsefbksdbfkalsjcuyasjehflkjhfalksdblhsgdfasudyfekjfalksdjfhlkasefyuiaydskfjashdflkasdhfksd
asc uyoi uawer k nb a dhcviua hsid ufe r bfa lskd jhv lkcj haius dy faj se fbks dbfkals jcuyasjehf lkjh falk sd blhsgdf asudyfekjf alk sdjfhlk asefyu iaydskfja shdflk as dhf ksd

Isso é , então a resposta mais curta em bytes vence.

Stephen
fonte
Sandbox
Stephen
A última palavra pode ser uma sequência vazia?
rahnema1
@ rahnema1 você quer dizer em uma saída de matriz?
23417 Stephen
Sim, último elemento da saída da matriz.
rahnema1
@ rahnema1 claro, já que se você se juntar à matriz no espaço, terá apenas um espaço à direita, o que eu permitiria.
23417 Stephen

Respostas:

5

Gelatina , 28 bytes

“¤Œæ׿®¬©¥¤‘Jẋ"$FẋLẊ‘1¦+\Ṭœṗ

Um link monádico pegando uma lista e retornando uma lista de listas.

Experimente online! (o rodapé separa a lista resultante de listas com espaços)

Quão?

Usa todas as porcentagens na distribuição arredondadas para o número inteiro mais próximo (estando dentro dos limites permitidos de 0,69%).

“¤Œæ׿®¬©¥¤‘Jẋ"$FẋLẊ‘1¦+\Ṭœṗ - Link: list (of characters), s
“¤Œæ׿®¬©¥¤‘                 - code page indexes = [3,19,22,17,11,8,7,6,4,3]
               $             - last two links as a monad:
            J                -   range of length = [1, 2, 3, 4, 5,6,7,8,9,10]
              "              -   zip with:
             ẋ               -     repeat list = [[1,1,1],...,[9,9,9,9],[10,10,10]]
                F            - flatten (into one list of length 100)
                  L          - length of s
                 ẋ           - repeat list (one list of length 100*length(s) with the
                             -              correct distribution of integer lengths)
                   Ẋ         - shuffle
                      ¦      - sparse application of:
                    ‘        -   increment
                     1       -   to indexes: 1 (offset indexes for the partition below)
                        \    - cumulative reduce by:
                       +     -   addition (e.g. [4,4,7,1,...] -> [4,8,15,16,...])
                         Ṭ   - untruth (yield a list with 1s at those indexes (1 indexed)
                          œṗ - partition s at truthy indexes (note: excess ignored)
Jonathan Allan
fonte
Teoricamente, seu script pode gerar a lista cujo primeiro elemento é uma string vazia. Não tenho certeza se é permitido pela pergunta.
@ThePirateBay sim, eu realmente só notei isso - eu preciso adicionar 1 ao primeiro elemento dos meus comprimentos cumulativos; será atualizado em breve para corrigir.
Jonathan Allan
Corrigido e explicação adicionada (não é possível pedir para permitir o espaço à esquerda, pois o comprimento da primeira palavra estaria realmente usando a distribuição incorreta).
27617 Jonathan Allan
4

PHP, 94 bytes

for(;$c=$argn[$k++];print$c." "[--$e])if(!$e)for($r=rand(0,71);$r>ord(x^"ywgSKAF:=?"[$e++]););

Execute como pipe -nRou experimente online .

demolir

for(;$c=$argn[$i++];            # loop $c through string
    print$c                         # 2. print current character,
        ." "                        # 4. if remaining length is 0, print space
        [--$e]                      # 3. decrement remaining length
    )
    if(!$e)                         # 1. if remaining length is 0,
        for($r=rand(0,71);              # get random value from 0 to 71
            $r>ord(x^"ywgSKAF:=?"[$e++])    # and increment $e while $r is > probability
        ;);

Nota: ywgSKAF:=?representa as probabidades crescentes -1:[1,15,31,43,51,57,62,66,69,71]

Titus
fonte
Eu me pergunto: as probabilidades mudariam se eu pedisse rand()todas as comparações? Caso contrário, eu poderia salvar 5 bytes.
Titus
1
Eles certamente mudariam, por exemplo, a probabilidade de comprimento 2 seria 70/72 * 16/72, superior a 14/72.
Ørjan Johansen
@ ØrjanJohansen Algo me disse que isso iria acontecer. Pena: Dessa forma, eu desperdiçaria pelo menos 5 bytes.
Titus
Esta não é a primeira vez que eu vejo uma solução PHP supostamente completa que não começou com <? ou <? php. Executar como um programa independente, o PHP precisa disso. Ou eu estou esquecendo de alguma coisa?
manassehkatz-Movendo 2 Codidact
@manassehkatz Está faltando Run as pipe with -nR. Ou seja, esse código deve ser um parâmetro para php, não um arquivo. Use echo <input> | php -nR '<code>'na linha de comando para executar.
Titus
3

Oitava, 108 bytes

@(s)mat2cell(s,1,[k=(w=repelems(1:10,[1:10;'AMOKGEDCBA'-63])(randi(72,1,n=nnz(s))))(cumsum(w)<=n) n-sum(k)])

Experimente online!

* Pega a string como entrada e gera uma matriz de strings.

* O último elemento da saída pode ser uma sequência vazia.

rahnema1
fonte
3

Python 2, 154 150 147 145 bytes

Tudo bem, esta é minha primeira tentativa no código de golfe. Direto com o código:

import numpy.random as r
def f(s):
 i=0
 while i<len(s):
    i+=r.choice(11,p=[x/72. for x in [0,2,14,16,12,8,6,5,4,3,2]])
    s=s[:i]+' '+s[i:]
    i+=1
 return s

O segundo travessão é por um caractere de tabulação, como você pode ver na minha versão do TIO: Experimente on-line .

O que faço é adicionar um espaço na string de acordo com a distribuição fornecida. Eu mudei minha distribuição usando:

import collections
dist = r.choice(11,100000,p=[x/72. for x in [0,2,14,16,12,8,6,5,4,3,2]])
print collections.Counter(dist)

O que me deu:

Word Length - Rounded Percentage as asked - Rounded Percentage as counted
1 - 2.78% - 2.794%
2 - 19.44% - 19.055%
3 - 22.22% - 22.376%
4 - 16.67% - 16.638%
5 - 11.11% - 11.246%
6 - 8.33% - 8.362%
7 - 6.94% - 7.063%
8 - 5.56% - 5.533%
9 - 4.17% - 4.153%
10 - 2.78% - 2.780%

O que eu acho que está correto o suficiente. Repito então o processo de adicionar um espaço até que o comprimento da minha string seja bem-sucedido. Também incremento meu índice de posição em um após adicionar um espaço. Espero que alguém possa me ajudar a jogar fora essa linha, mas não vi como tirá-la sem falsificar o primeiro espaço.

Ao ver meu texto, reconheço que tenho que aprender muito sobre este site. Alguém poderia me vincular um guia sobre como usar a função de resposta Stackoverflow nos comentários para que eu possa aprender nas minhas próximas postagens.


Editar:

Aparentemente, ao reler minha postagem, descobri uma maneira de me livrar do i + = 1. Então eu salvei 4 bytes fazendo isso. O novo código fica assim:

import numpy.random as r
def f(s):
 i=-1
 while i<len(s):
  i+=r.choice(11,p=[x/72. for x in[0,2,14,16,12,8,6,5,4,3,2]])+1
  s=s[:i]+' '+s[i:]
 return s

Experimente online!


Editar:

Eu descobri que posso remover algumas quebras de linha.

import numpy.random as r
def f(s):
 i=-1
 while i<len(s):i+=r.choice(11,p=[x/72. for x in[0,2,14,16,12,8,6,5,4,3,2]])+1;s=s[:i]+' '+s[i:]
 return s


Edit: Modifiquei minha importação e coloquei a definição de i dentro da função.

from numpy.random import*
def f(s,i=-1):
 while i<len(s):i+=choice(11,p=[x/72. for x in[0,2,14,16,12,8,6,5,4,3,2]])+1;s=s[:i]+' '+s[i:]
 return s

Experimente online!

Simon
fonte
Bem-vindo à programação de quebra-cabeças e código de golfe! Bom primeiro post! Editei sua resposta um pouco para melhorar a formatação (título, destaque da sintaxe). Você pode dar uma olhada no que mudou para ver os comandos para suas futuras postagens. (Eu não tenho qualquer ligação a dar-lhe, infelizmente, mas espero que alguém o fará)
Dada
Obrigado pela boas-vindas e formatação do meu texto. Isso me ajudou e eu já o usei no meu Edit.
27417 Simon
2

Dyalog APL, 90 bytes

{k←⍵⋄{' '~⍨(2⊃⍵)↓k↑⍨⊃⍵}¨(↓(o[1;2]),0),↓o←1↓⍉2(1-⍨≢⍵)⍴+\((2 14 16 12 8,⌽1+⍳5)\⍳10)[72?⍨≢⍵]}

Experimente online! Clique em Executar algumas vezes para ver como isso muda.

Quão?

72?⍨≢⍵ - rolar 72 dados de lados dos tempos de entrada

[...] - indexar dentro

(2 14 16 12 8,⌽1+⍳5)\⍳10- expanda o intervalo de 10 em 2 14 16 12 8 6 5 4 3 2(para criar aleatório ponderado)

+\ - soma cumulativa

⍉2(1-⍨≢⍵)⍴- forma como uma mesa compactada x y zz x, x y, y z

o←1↓ - solte o primeiro elemento

(↓(o[1;2]),0),↓o - encase com sua primeira coordenada emparelhada com 0

¨ - para cada par (x, y)

(2⊃⍵)↓k↑⍨⊃⍵ - recebe entrada do índice x para y

' '~⍨ - e remover espaços

Uriel
fonte
2

Python 2 , 155 bytes

from random import*
def f(s):
 i=sum([[i+1]*[2,14,16,12,8,6,5,4,3,2][i]for i in range(10)],[])[randint(0,71)]
 return s if len(s)<11else s[:i]+' '+f(s[i:])

Experimente online!

Chas Brown
fonte
2

Mathematica, 164 bytes

(s=Length[c=Characters@#];t=0;l={};While[t<s,If[t+(r=RandomChoice[{2,14,16,12,8,6,5,4,3,2}->Range@10])<=s,l~AppendTo~r];t=Tr@l];""<>#&/@FoldPairList[TakeDrop,c,l])&


pega uma string quando a entrada
gera uma matriz de strings

J42161217
fonte
2

Carvão , 43 39 bytes

FθF⁺¹I‽⪫Eχ×Iκ⌕᧔v↷£o8″!”κω⊞υ⎇κω Fθ⁺ι⊟υ

Experimente online! Link é a versão detalhada do código. Gera um espaço à direita se a última palavra tiver o tamanho exato escolhido aleatoriamente.

Neil
fonte
Sim, parece muito longo: / Alguma idéia para novos recursos que o encurtariam?
somente ASCII
@ Somente ASCII Não consigo pensar em uma boa maneira de gerar a tabela de probabilidades, que já está acima de 50% do código. Seria bom se eu não tivesse que resolver o problema Assign(Slice(q, i), q);.
315 Neil
Que iria trabalhar, apenas é ambígua, não inteiramente certo da melhor maneira de corrigir isso, desculpe
ASCII-only
Woah tanto aninhamento
apenas ASCII
@ Somente ASCII Quem se importa se salva bytes?
315 Neil
2

Perl 5 , 107 bytes

@B=((1,10,9,5,2)x2,(2,3,4)x12,(5,6)x6,7,(3,7,8)x4,9);while(10<length){$i=$B[rand 72];s/.{$i}//;print"$& "}

Experimente online!

106 bytes de código +1 para -p

Xcali
fonte
Bem-vindo ao site! É bom ver um novo jogador de golfe Perl, ótima resposta! (você ainda pode salvar alguns bytes ). Além disso, recomendo adicionar algumas explicações, para que pessoas não-Perl tenham uma idéia de como você fez isso (e mesmo para o codificador Perl, economiza um pouco de tempo), mas isso não é obrigatório e depende apenas de você.
Dada
1

Ruby , 96 + 1 = 97 bytes

Usa a -pbandeira.

i=0
m=[3,19,22,17,11,8,7,6,4,3].flat_map{|k|[i+=1]*k}
i=0
$_[i-1,0]=' 'while~/$/+1>i+=1+m.sample

Experimente online!

Value Ink
fonte
1

> <> , 168 152 bytes

<v?(0:i
~/<r
/x\/oo \
012\oo~\!/ !ox\
\v/:1=?^?\ooo>>
 x^
v\:1\/>> o
|/o\=\x^!/
voo/? >x
v\o~/ v_
>" "\?\x>xoo\
^oooooo<<< \
^.22/ \>x!/xv
^ooooooo_o<<<

Experimente online ou assista no playground de peixes !

A aleatoriedade é complicada em> <>: existe apenas uma instrução aleatória x, que define a direção do peixe para cima, baixo, esquerda ou direita. Este é um programa complicado, então aqui está um diagrama com código de cores para ajudá-lo:

Código codificado por cores!

Tentei dividir as probabilidades em partes para que as probabilidades dentro e entre as partes fossem bastante simples (preferindo, digamos, 1/3 a 25/72). Eu fiz isso da seguinte maneira:

Árvore de probabilidades

O peixe começa no bit cinza do código ( X ). Este é um código> <> bastante padrão para ler todas as entradas. Fica mais interessante, então vamos seguir em frente.

Em seguida, o peixe chega às seções verde clara e escura ( Y ). Você pode notar na árvore de probabilidade que as três ramificações principais somam 1/3 e que cada uma dessas ramificações se divide em uma sub-ramificação 2/3 e uma sub-ramificação 1/3. As seções verdes do código cobrem esses dois níveis da árvore. Primeiro, escolhemos um número aleatório de 0, 1, 2 com a mesma chance de cada um, no lobo superior do bit verde claro. Podemos simular uma chance de 1/3 usando a instrução de quatro direções xcortando uma das saídas para que ele apenas redirecione o peixe de volta para o x- então existem apenas três rotas de fuga do x, e por simetria elas têm probabilidades iguais.

O próximo x, um pouco abaixo deste, envia o peixe para o ^próximo a ele com 2/3 de chance - observe que o peixe gira em torno se nadar saindo da x- e desce para um \com chance de 1/3. O peixe então nada ao longo de uma das duas caudas da seção verde-clara. Essas caudas são funcionalmente iguais: cada uma verifica se pressionamos 0, 1 ou 2 anteriormente e ramificamos de acordo. E isso completa os dois primeiros níveis da árvore.

As próximas seis seções ( A - F ), em essência, usam mais xs para ramificar ainda mais o peixe e, em seguida, usam algum número de os para imprimir várias letras da entrada. Essas seções variam de simples (por exemplo, azul escuro,  C , que imprime apenas três letras) a, bem, não tão simples (por exemplo, laranja, D , que precisa de dois xs para simular uma divisão de 3 / 8–5 / 8, imprimindo letras em estágios múltiplos). Os detalhes destes são deixados como um exercício. (Estou particularmente satisfeito com o amarelo, E , que envia o peixe em um loop-the-loop!)

Após cada um desses galhos, o peixe finalmente atinge a seção rosa ( Z ). Isso reúne todos os galhos, imprime um espaço e, finalmente, faz o peixe pular para a posição (2,2) na grade e começar de novo no primeiro x.


Caso a explicação "complicada" acima não o convença de que isso fornece as probabilidades corretas, eu também a testei em uma string de entrada com 65.000 caracteres (64 KiB, apenas 13 segundos no TIO!) E a distribuição resultante dos comprimentos das palavras foi

{{1,0.027377},{2,0.191237},{3,0.226599},{4,0.164128},{5,0.113064},{6,0.0818627},{7,0.0703885},{8,0.0543515},{9,0.0426089},{10,0.0283835}}

Essas probabilidades estão no máximo 0,0044 das probabilidades esperadas.

Não é uma árvore
fonte