Pato, Pato, Josephus


49

Dado um array inteiro:

  1. Comece do primeiro número
  2. Avança n posições onde n é o valor da posição atual
  3. Exclua a posição atual, tornando a próxima posição a posição atual.
  4. Vá para a etapa 2 até que haja um número restante
  5. Imprimir esse número

Regras

A matriz envolve (o próximo número após o último número na matriz é o primeiro número).

Um zero se remove (obviamente).

Números negativos não são permitidos como entrada.

Casos de teste

[1] => 1
[1,2] => 1
[1,2,3] => 3
[1,2,2] => 1
[1,2,3,4] => 1
[6,2,3,4] => 4
[1,2,3,4,5] => 5
[0,1] => 1
[0,0,2,0,0] => 0

Exemplo passo a passo

[1,4,2,3,5]
 ^          start from the first position
   ^        jump 1 position (value of the position)
[1,  2,3,5] remove number in that position
     ^      take next position of the removed number (the 'new' 'current' position)
         ^  jump 2 positions
[1,  2,3  ] remove number in that position
 ^          take next position (looping on the end of the array)
     ^      jump 1 position
[1,    3  ] remove number in that position
       ^    take next position (looping)
 ^          jump 3 positions (looping on the end of the array)
[      3  ] remove number in that position
print 3

Exemplo 2

[4,3,2,1,6,3]
 ^            start from the first position
         ^    jump 4 positions
[4,3,2,1,  3] remove number in that position    
           ^  take next position
     ^        jump 3 positions
[4,3,  1,  3] remove number in that position    
       ^      take next position
           ^  jump 1 positions
[4,3,  1    ] remove number in that position    
 ^            take next position
   ^          jump 4 positions
[4,    1    ] remove number in that position    
       ^      take next position
 ^            jump 1 position
[      1    ] remove number in that position
print 1

Este é o , a resposta mais curta em bytes vence!


14
Bom primeiro desafio!
Luis Mendo

2
@LuisMendo Sim .. a "saltar como um ..." desafios
J42161217

2
@Jenny_mathy Eu não pensei que haveria um similar, mas, como Luis disse, a variedade envolvente representa um desafio interessante para o golfe. Eu acho que: /
workoverflow

3
@EriktheOutgolfer Não é realmente um idiota. Os elementos são indistinguíveis e o tamanho da etapa é fixo. Luis está muito mais perto, mas ainda assim suficientemente diferente, eu acho.
Martin Ender

3
Ele realmente precisa imprimir o número final ou pode apenas devolvê-lo? Ele precisa realmente retornar o número, ou pode simplesmente operar na matriz no local para que, após a execução da função, a matriz contenha apenas o número?
iamnotmaynard

Respostas:


9

Casca , 7 bytes

Isso retorna o resultado como uma lista singleton

ΩεSotṙ←

Experimente online!

Explicação

Ω               Until
 ε              the result is a singleton list
     ṙ          Rotate left by
  S   ←         the first element
   ot           Then remove the first element  

7

Haskell , 54 50 48 bytes

f[x]=x
f(x:r)=f$snd<$>zip r(drop(x+1)$cycle$x:r)

Experimente online!

Explicação:

  • f[x]=x: Se a lista fornecida for uma lista singleton, retorne seu elemento.
  • f(x:r)=f$ ...: Caso contrário, recursivamente aplique fà seguinte lista:
    • Os elementos da lista atual deram um ciclo infinito ( cycle$x:r),
    • com os primeiros x+1elementos removidos ( drop(x+1)$),
    • e truncado para o comprimento de r. ( snd<$>zip ré uma alternativa mais curta para take(length r)).

Versão anterior de 54 bytes:

f=(%)=<<head
_%[x]=x
n%(x:r)|n<1=f r|s<-r++[x]=(n-1)%s

Experimente online!



6

MATL , 21 bytes

1`yy)+ynX\[]w(5Mynq]x

Experimente online! Ou verifique todos os casos de teste .

Explicação

1        % Push 1: current position in the array
`        % Do...while
  yy     %   Duplicate top two elements in the stack. Takes input implicitly
         %   in the first iteration.
         %   STACK: array, position, array, position
  )      %   Get specified entry in the array
         %   STACK: array, position, selected entry
  +      %   Add
         %   STACK: array, position (updated)
  y      %   Duplicate from below
         %   STACK: array, position, array
  n      %   Number of elements of array
         %   STACK: array, position, number of elements or array
  X\     %   1-based modulus
         %   STACK: array, position (wrapped around)
  []     %   Push empty array
         %   STACK: array, position, []
  w      %   Swap
         %   STACK: array, [], position
  (      %   Write value into specified entry in array. Writing [] removes
         %   the entry
         %   STACK: array (with one entry removed)
  5M     %   Push latest used position. Because of the removal, this now
         %   points to the entry that was after the removed one
         %   STACK: array, position
  y      %   Duplicate from below
         %   STACK: array, position, array
  n      %   Number of elements of array
         %   STACK: array, position, number of elements of array
  q      %   Subtract 1
         %   STACK: array, position, number of elements of array minus 1
]        % End. If top of the stack is nonzero, proceed with next iteration
         % STACK: array (containing 1 entry), position
x        % Delete. Implicitly display
         % STACK: array (containing 1 entry)

11
Nota: o uso de rotações de lista em vez de manter um ponteiro provavelmente tornará isso muito mais curto.
Erik the Outgolfer

11
@ Erik Obrigado. Mas agora que adicionei a explicação, acho que vou deixar assim
Luis Mendo

Bem, você sempre pode remover a explicação, ela será mantida na história :)
Erik the Outgolfer


5

CJam , 15 bytes

l~_,({_0=m<1>}*

Experimente online!

Explicação

Em vez de acompanhar um ponteiro, apenas mudo a matriz ciclicamente para que o elemento atual esteja sempre à frente.

l~     e# Read and evaluate input.
_,(    e# Get its length L and decrement to L-1.
{      e# Run this block L-1 times...
  _0=  e#   Get the first element X.
  m<   e#   Rotate the array left by X positions.
  1>   e#   Discard the first element.
}*
       e# The final element remains on the stack and gets printed implicitly.

Uma alternativa divertida que infelizmente não salva bytes:

l~_{;m<1>_0=}*;

5

Flacidez Cerebral , 88 bytes

([[]]()){({}<(({})){({}<({}<([]){({}{}<>)<>([])}{}>)<>{({}[<>[]])<>}<>>[()])}{}{}>())}{}

Experimente online!

Explicação

([[]]())                      Push negative N: the stack height - 1
{({}< … >())}{}               Do N times
     (({}))                     Duplicate M: the top of the stack
     {({}< … >[()])}{}          Do M times 
                                  Rotate the stack by 1:
          ({}< … >)               Pop the top of the stack and put it back down after
          ([]){({}{}<>)<>([])}{}  Pushing the rest of the stack on to the other one, in reverse, with the stack height added to each element (to ensure that all are positive)
          <>{({}[<>[]])<>}<>      Push the rest of the stack back, unreversing, and subtracting the stack height from each element
                      {}        Pop the top of stack

11
Um golfe muito estranho, mas aqui está em 88 bytes .
Wheat Wizard

11
@WheatWizard Nice, surpreendentemente eu tentei algo assim mais cedo.
H.PWiz

Eu nunca sei como as pessoas podem codificar assim! existe um tradutor de pseudo-código ou algo assim?
workoverflow

11
@ workoverflow não, é honestamente mais fácil do que parece. Foi muito assustador antes de começar, mas quando os comandos são simples assim, é fácil aprender.
H.PWiz

5

Python 2 , 55 bytes

def f(a):
 while a[1:]:l=a[0]%len(a);a[:]=a[-~l:]+a[:l]

Experimente online!

Saídas como uma lista de singleton, conforme permitido por padrão . Economizei alguns bytes graças a Dennis , lembrando-me que a modificação do argumento da função é permitida.

Como funciona

  • def f(a)- Define uma função com um parâmetro a.

  • while a[1:]:- Embora ao primeiro elemento removido seja verdade, execute o bloco de código a seguir. Uma lista com um elemento ou mais é verdadeira e listas vazias são falsas no Python; portanto, isso irá parar quando aatingir 1.

  • l=a[0]%len(a)- Pegue o primeiro elemento e obtenha o restante de sua divisão pelo comprimento de a. Atribua o resultado a l.

  • a[:]=a[-~l:]+a[:l]- Gire apara a esquerda os lelementos e remova o primeiro, enquanto atribui isso ao alocal.


Python 2 , 63 bytes

f=lambda a,i=0:a[1:]and f(a,a.pop(((a*-~i)[i]+i)%len(a))+1)or a

Experimente online!

Embora mais longo, isso parece muito mais elegante. Também obrigado a ovs por ajudar no chat.


11
Você não poderia fazer algo como a,*b=input()(python3) e salvar alguns bytes? No entanto, eu não tenho certeza de como isso afetaria lea fatia
Rod

11
@Rod Eu não penso assim, eu precisaria para avaliar a entrada muito em Python 3
Mr. Xcoder


4

Geléia , 9 bytes

ṙḷ/ḊµL’$¡

Experimente online!

-2 bytes graças a user202729

Explicação

ṙḷ/ḊµL’$¡  Main Link
     L’$¡  Repeat <length - 1> times
ṙ          Rotate left by
 ḷ/        The first element (from JHT; thanks to user202729)
   Ḋ       Take all but the first element



3

Mathematica, 36 bytes

usa o algoritmo de Martin

#//.l:{x_,__}:>Rest@RotateLeft[l,x]&

-5 bytes de Misha Lavrov e Martin Ender

Experimente online!


11
Você pode salvar dois bytes usando o padrão para selecionar o primeiro elemento #//.{x_,y__}:>Rest@RotateLeft[{x,y},x]&. (Este pára quando há apenas um elemento porque {a}não corresponde ao padrão {x_,y__}.)
Misha Lavrov

11
O @MishaLavrov não pode testar no momento, mas você provavelmente pode reduzi-lo ainda mais, excluindo y, chamando a lista inteira le usando em lvez de {x,y}.
Martin Ender

11
@MartinEnder Você quer dizer assim - #//.l:{x_,__}:>Rest@RotateLeft[l,x]&?
Misha Lavrov

11
@MishaLavrov yep.
Martin Ender

3

J , 21 17 bytes

-4 bytes graças ao FrownyFrog

((1<#)}.{.|.])^:_

Experimente online!

Original:

([:}.{.|.])^:(1<#)^:_

Como funciona:

^:_ repita até o resultado parar de mudar

^:(1<#) se o comprimento da lista for maior que 1

{.|.] gire a lista para a esquerda seu primeiro item vezes

[:}. solte o primeiro elemento e tampe o garfo

Experimente online!


@ FrownyFrog Obrigado, eu não tentei isso - é muito melhor!
Galen Ivanov

3

JavaScript (ES6), 54 60 bytes

Economizou 1 byte graças à versão fixa @Shaggy
(+6 bytes)

Modifica a matriz de entrada , que é reduzida a um singleton.

f=(a,p=0)=>1/a||f(a,p=(p+a[p%(l=a.length)])%l,a.splice(p,1))

Casos de teste

Quão?

Aplicamos recursivamente o algoritmo descrito no desafio. Somente a condição de parada 1/apode parecer um pouco estranha. Ao aplicar um operador aritmético:

  • Matrizes de mais de um elemento são coagidas NaNe 1/NaNtambém são NaN(falsas).
  • Matrizes de exatamente um número inteiro são coagidas a esse número inteiro, levando a um 1/0 = +Infinityou 1/N = positive floata N> 0 (ambos de verdade).
f = (a, p = 0) =>                 // a = input array, p = pointer into this array
  1 / a ||                        // if a is not yet a singleton:
    f(                            //   do a recursive call with:
      a,                          //     a
      p = (                       //     the updated pointer
        p + a[p % (l = a.length)] //
      ) % l,                      //
      a.splice(p, 1)              //     the element at the new position removed
    )                             //   end of recursive call

Vendo como splicemodifica a matriz original, você poderia fazer f=(a,p=0)=>1/a||f(a,p=p+a[p]%a.length,a.splice(p,1))para 52 bytes
Shaggy

parece que não dá o resultado certo para o segundo exemplo passo a passo, f=(a,p=0)=>1/a?a:f(a,p=(p%a.length+a[p%a.length])%a.length,a.splice(p,1))é ok, mas pode ser otimizado
Nahuel FOUILLEUL

@NahuelFouilleul Oops. Eu pensei que em algum momento os parênteses ao redor p+a[p]poderiam ser removidos. O que - é claro - não é o caso. Obrigado por denunciar isso!
Arnauld

Veja este consenso , que @Neil chamou minha atenção aqui .
Shaggy

@ Shagy Oh, entendo. Obrigado! (Eu perdi o seu link TIO 1ª vez ...)
Arnauld


3

Java 8, 79 bytes

Este lambda aceita ae Stack<Integer>retorna um intou Integer.

l->{for(int i=0,s=l.size();s>1;)l.remove(i=(i+l.get(i%s))%s--);return l.pop();}

Experimente Online

Ungolfed

l -> {
    for (
        int i = 0, s = l.size()
        ; s > 1
        ;
    )
        l.remove(
            i = (i + l.get(i % s)) % s--
        );
    return l.pop();
}

Agradecimentos

  • -2 bytes graças a Nahuel Fouilleul

11
i%=spode ser removido se l.get(i)alterado porl.get(i%s)
Nahuel Fouilleul 13/12

2

Pitão , 9 bytes

.WtHt.<Zh

Experimente aqui!

Isso gera o resultado como uma lista de singleton, conforme permitido por padrão .

Como funciona

.WtHt.<Zh ~ Full program.

.W        ~ Functional while. It takes three arguments, two functions: A and B
            and a starting value, which in this case is automatically assigned
            to the input. While A(value) is truthy, value is set to B(value).
            Returns the ending value. A's argument is H and B's is Z.
  tH      ~ A (argument H): Remove the first element of H. A singleton list
            turns into [], which is falsy and thus breaks the loop. Otherwise,
            it is truthy and the loops goes on until the list reaches length 1.
     .<Zh ~ B (argument Z): Cyclically rotate Z by Z[0] places, whereas Z[0]
            represents the first element of Z.
    t     ~ And remove the first element.

Nota: Se você não quiser ver esses colchetes, basta adicionar hou ena frente de todo o código.


2

Rápido , 87 bytes

func f(a:inout[Int]){var i=0,c=0;while(c=a.count,c>1).1{i=(i+a[i%c])%c;a.remove(at:i)}}

Retorna como uma lista singleton por modificar a entrada . Experimente online!

Explicação

func f(a:inout[Int]){
  var i=0,c=0;            // Set the index i to 0
  while(c=a.count,c>1).1{ // While the length of the list > 0:
    i=(i+a[i%c])%c;       //  Add a[i] to i and loop back using modulo
    a.remove(at:i)        //  Remove a[i]
  }
}

2

Perl 6 , 46 45 bytes

(-1 byte graças a Brad Gilbert)

{($_,{(|$_ xx*)[.[0]+(1..^$_)]}...1)[*-1][0]}

Experimente online!

($_, { ... } ... 1)gera uma sequência de listas, começando com a lista de entrada $_, cada elemento sucessivo sendo gerado pela expressão entre colchetes e finalizando quando a lista combina de forma inteligente 1--ie, tem um comprimento de 1. O final [* - 1]obtém o elemento final e o final [0]tira o único elemento dessa lista de singleton.

(|$_ xx *)gera uma cópia plana e infinitamente replicada do elemento atual. Essa lista é indexada com o intervalo .[0] + (1 ..^ $_)para extrair a próxima lista finita da série.


11
mente soprado oO
Adrian

[*-1][0]pode ser combinado para [*-1;0]salvar um byte. Também 1..$_-1é melhor escrever como 1..^$_salvar novamente um byte.
Brad Gilbert b2gills

@ BradGilbertb2gills eu tentei [*-1;0], mas parece não ser equivalente de alguma forma. A função então retorna uma lista em vez de um número.
18717 Sean

Isso não impede a 1..^$_otimização
Brad Gilbert b2gills

1

Perl 5 , 47 43 41 + 2 ( -ap) = 43 bytes

$\=splice@F,($_+=$F[$_%@F])%@F,1while@F}{

Experimente online!

Recebe a entrada como números separados por espaço.


parece que não faz exatamente o mesmo que o exemplo passo a passo seguinte faz, mas é mais longo$x%=@F,splice@F,$x=($x+$F[$x])%@F,1while$#F;$_="@F"
Nahuel FOUILLEUL

11
uau oO Preciso começar meu jogo.
Adrian



1

Java 8 , 325 bytes

Golfe:

static void n(Integer[]j){Integer[]h;int a=0;h=j;for(int i=0;i<j.length-1;i++){if(h.length==a){a=0;}a=(a+h[a])%h.length;h[a]=null;h=m(h);}System.out.print(h[0]);}static Integer[] m(Integer[]array){Integer[]x=new Integer[array.length-1];int z=0;for(int i=0;i<array.length;i++){if(array[i]!=null){x[z]=array[i];z++;}}return x;}

Ungolfed:

 interface ArrayLeapFrog {
static void main(String[] z) throws Exception {
    Integer[] j = {6, 2, 3, 4};
    n(j);
}

static void n(Integer[] j) {
    Integer[] h;
    int a = 0;
    h = j;
    for (int i = 0; i < j.length - 1; i++) {
        if (h.length == a) {
            a = 0;
        }
        a = (a + h[a]) % h.length;
        h[a] = null;
        h = m(h);
    }
    System.out.print(h[0]);
}

static Integer[] m(Integer[] array) {
    Integer[] x = new Integer[array.length - 1];
    int z = 0;
    for (int i = 0; i < array.length; i++) {
        if (array[i] != null) {
            x[z] = array[i];
            z++;
        }
    }
    return x;
  }
}

4
Bem vinda! Algumas dicas: não é necessário contar as staticpalavras - chave aqui. Normalmente, as soluções de vários métodos são implementadas como membros não estáticos de uma classe e maincria uma instância para teste. Além disso, se você fizer dessa maneira, suporta o Java 7 e poderá enviar como simplesmente uma solução "Java". Para referência futura, o formato de entrada tende a ser bastante flexível aqui; portanto, por exemplo, você pode optar por receber a entrada como List(o que é bastante útil para esse problema).
Jakob

1

APL + WIN, 36 bytes

¯1↑⍎¨(1⌈¯1+⍴v←,⎕)⍴⊂'v←(1<⍴v)↓v[1]⌽v'

Explicação:

Solicita a entrada da tela.

'v←(1<⍴v)↓v[1]⌽v' Loop logic as a string

 (1<⍴v)↓ only drop the first when number of elements n>1

 (1⌈¯1+⍴v←,⎕)⍴⊂ create a nested vector of logic of length 1 max n-1

 ⍎¨ execute each element of the nested vector in turn

¯1↑ take answer from executing final element

1

Python 2, 61 bytes

def f(x):
 while x[1:]:y=x[0]%len(x);x=x[y+1:]+x[:y]
 print x

11
Eu sei que existem várias respostas em python, mas achei que poderia adicionar as minhas.
Rɪᴋᴇʀ

1

JavaScript, 58 56 59 bytes

let f =

a=>{for(i=0,k=a.length;k>1;)i+=a[i%=k],a.splice(i%=k--,1)}
<h2>Test</h2>
Enter or paste a valid array literal within square brackets and click Run.
<blockquote>
   <input id = "array" type="text" length="20">
   <button type="button" onclick="run()">Run</button>
</blockquote>
Result: <pre id="o"></pre>

<script>
    function run() {
       let a = JSON.parse(array.value);
       f(a);
       o.textContent = a;
    }
</script>

Retorna o resultado como o único elemento restante na matriz de entrada que é atualizado no local.

Dois bytes salvos usando uma instrução separada por vírgula em vez de uma instrução de bloco no corpo do loop for! Três bytes perdidos para pular de um elemento excluído no final da matriz (:

Menos golfe:

a => {
    for(i=0,k=a.length;k>1;) // once less than array length
        i+=a[i%=k],          // the new index
        a.splice(            // delete an element
           i%=k--,           // ensuring index is within array,
                             // and post decrement loop count
           1
        )
}

Isso parece dar a resposta errada para [3, 5, 7, 9].
Neil

Errado por [3,5,7,9]. Valor esperado 5
edc65

A função não retornar o valor, eu não tenho certeza se a contagem de bytes é correcta manutenção isso em mente, uma vez que não pode trabalhar em seu próprio ...
Brian H.

@ edc65 e Neil, obrigado - o índice de um elemento excluído no final da matriz não estava sendo ajustado para o início da matriz reduzida.
traktor53

@BrianH. a função de modificar seu parâmetro, não há consenso sobre o que codegolf.meta.stackexchange.com/a/4942/21348
edc65

1

Flak cerebral , 104 bytes

H.PWiz tem uma resposta mais curta aqui que eu ajudei a fazer, você deve conferir.

([[]]()){({}()<(({})){({}[()]<({}<(([])<{{}({}<>)<>([])}{}<>>)<>>)<>{({}[()]<({}<>)<>>)}{}<>>)}{}{}>)}{}

Experimente online!

Explicação

([[]]())   #Push 1 minus stackheight
{({}()<    #N times
 (({}))    #Get a copy of the top
 {({}[()]< #N times
  ({}<(([])<{{}({}<>)<>([])}{}<>>)<>>)<>{({}[()]<({}<>)<>>)}{}<>
           #Roll the top to the bottom (From the wiki)
 >)}{}     #End loop
 {}        #Remove one value
>)}{}      #End loop

Eu pensei que iria competir . Então eu percebi que o meu era quase exatamente a mesma que a sua , além de um "rolo top" diferente
H.PWiz

Eu vi isso ;). Usar o fato de que tudo é não negativo é bastante inteligente.
Assistente de trigo


1

R , 111 117 126 bytes

Graças ao @ Giuseppe por jogar 11 bytes ao mudar para um loop while, obtive outros 4 removendo a função e lendo diretamente a entrada do usuário.

Não me sinto muito bem com o que foi necessário para chegar lá - tenho certeza de que existe uma solução mais elegante.

i=scan();m=1;while((l=sum(i|1))-1){j=i[m];p=`if`(j+m>l,j%%l+!m-1,j+m);p=`if`(!p,m,p);i=i[-p];m=`if`(p-l,p,1)};i

Experimente online!

Código ungolfed

i=scan()
m=1
while((l=sum(i|1))-1){
  j=i[m]
  p=`if`(j+m>l,j%%l+!m-1,j+m)
  p=`if`(!p,m,p)
  i=i[-p]
  m=`if`(p-l,p,1)
}
i

117 bytes - nota que desde que esta é uma função recursiva, o nome f=precisa ser incluído
Giuseppe

11
Achei esse desafio bastante difícil com uma linguagem de índice 1 sem rotações de matriz; isso é potencialmente 1-3 bytes mais curto com um whileloop, eu acho.
Giuseppe


meu 115 byter anterior era inválido, pois ambos esquecemos a f=parte da função recursiva. :(
Giuseppe

Atualizei a pontuação antiga e a nova para refletir a recursividade :) Com o loop 'while', joguei outros 4 bytes usando scan.
Mark
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.