Esta pergunta é baseada no quebra-cabeça de posicionamento numérico Towers (também conhecido como Arranha-céus), que você pode jogar online . Seu objetivo é pegar uma solução para o quebra-cabeça e determinar as pistas - o número de torres visíveis ao longo de cada linha e coluna. Isso é código de golfe, e o menor número de bytes vence.
Como funciona a Towers
A solução para um quebra-Towers é um quadrado latino - uma n*n
grade em que cada linha e coluna contém uma permutação dos números 1
através n
. Um exemplo para n=5
é:
4 3 5 2 1
5 4 1 3 2
1 5 2 4 3
2 1 3 5 4
3 2 4 1 5
Cada linha e coluna é rotulada com uma pista em cada extremidade, como:
2 3 1 4 5
v v v v v
2 > 4 3 5 2 1 < 3
1 > 5 4 1 3 2 < 4
2 > 1 5 2 4 3 < 3
3 > 2 1 3 5 4 < 2
3 > 3 2 4 1 5 < 1
^ ^ ^ ^ ^
2 2 2 2 1
Cada pista é um número de 1
até n
que informa quantas torres você "vê" olhando ao longo da linha / coluna dessa direção, se os números forem tratados como torres com essa altura. Cada torre bloqueia torres mais curtas atrás dela. Em outras palavras, as torres que você pode ver são as mais altas do que qualquer torre antes delas.
Por exemplo, vamos olhar para a primeira linha.
2 > 4 3 5 2 1 < 3
Tem uma pista da 2
esquerda, porque você pode ver o 4
e o 5
. O 4
bloqueia a 3
visão e 5
bloqueia tudo o resto. Da direita, você pode ver 3
torres: 1
, 2
, e 5
.
Requisitos do programa
Escreva um programa ou função que capte a grade de números e produza ou imprima as pistas, girando no sentido horário a partir do canto superior esquerdo.
Entrada
Um n*n
quadrado latino com 2<=n<=9
.
O formato é flexível. Você pode usar qualquer estrutura de dados que represente uma grade ou lista contendo números ou caracteres de dígitos. Você pode precisar de um separador entre as linhas ou nenhum separador. Algumas possibilidades são uma lista, uma lista de listas, uma matriz, uma sequência separada por token, como
43521 54132 15243 21354 32415,
ou uma string sem espaços.
Você não é dado n
como parte da entrada.
Saída
Retorne ou imprima as pistas começando no canto superior esquerdo e indo no sentido horário. Então, primeiro as pistas superiores lendo para a direita, depois as pistas certas lendo para baixo, depois as pistas inferiores lendo para a esquerda, e as pistas esquerdas para cima.
Isso seria 23145 34321 12222 33212
para o exemplo anterior
2 3 1 4 5
v v v v v
2 > 4 3 5 2 1 < 3
1 > 5 4 1 3 2 < 4
2 > 1 5 2 4 3 < 3
3 > 2 1 3 5 4 < 2
3 > 3 2 4 1 5 < 1
^ ^ ^ ^ ^
2 2 2 2 1
Assim como para a entrada, você pode usar uma lista, sequência ou qualquer estrutura ordenada. Os quatro "grupos" podem ser separados ou não, em uma estrutura aninhada ou plana. Mas, o formato deve ser o mesmo para cada grupo.
Exemplos de casos de teste:
(Seu formato de entrada / saída não precisa ser o mesmo que este.)
>> [[1 2] [2 1]]
[2 1]
[1 2]
[2 1]
[1 2]
>> [[3 1 2] [2 3 1] [1 2 3]]
[1 2 2]
[2 2 1]
[1 2 3]
[3 2 1]
>> [[4 3 5 2 1] [5 4 1 3 2] [1 5 2 4 3] [2 1 3 5 4] [3 2 4 1 5]]
[2 3 1 4 5]
[3 4 3 2 1]
[1 2 2 2 2]
[3 3 2 1 2]
>> [[2 6 4 1 3 7 5 8 9] [7 2 9 6 8 3 1 4 5] [5 9 7 4 6 1 8 2 3] [6 1 8 5 7 2 9 3 4] [1 5 3 9 2 6 4 7 8] [3 7 5 2 4 8 6 9 1] [8 3 1 7 9 4 2 5 6] [9 4 2 8 1 5 3 6 7] [4 8 6 3 5 9 7 1 2]]
[4 2 2 3 3 3 3 2 1]
[1 3 3 2 2 2 2 3 3]
[4 3 2 1 2 3 3 2 2]
[3 1 2 4 3 3 2 2 5]
Para sua conveniência, aqui estão os mesmos casos de teste em um formato de sequência simples.
>> 1221
21
12
21
12
>> 312231123
122
221
123
321
>> 4352154132152432135432415
23145
34321
12222
33212
>> 264137589729683145597461823618572934153926478375248691831794256942815367486359712
422333321
133222233
432123322
312433225
≢¨∪¨↓⌈\(⍉⍪⌽⍪⍉∘⌽∘⊖⍪⊖)
Python 2, 115 bytes
Há uma enorme quantidade de lista rolando por aí.
Recebe a entrada como uma lista aninhada (por exemplo, ligue com
T([[4,3,5,2,1],[5,4,1,3,2],[1,5,2,4,3],[2,1,3,5,4],[3,2,4,1,5]])
). Saída é uma lista simples e plana.Ungolfed:
Alternativa 115:
Não faço ideia por que isso funciona com uma compreensão de lista, mas sim
NameError
com uma compreensão definida ...Um pouco longo, mas se alguém estiver interessado - sim, é possível obter isso em um lambda!
Pitão , 25 bytes
Porta Pyth obrigatória.
Insira a lista via STDIN, por exemplo
[[4, 3, 5, 2, 1], [5, 4, 1, 3, 2], [1, 5, 2, 4, 3], [2, 1, 3, 5, 4], [3, 2, 4, 1, 5]]
.Experimente on-line ... é o que eu diria, mas, infelizmente, por razões de segurança, o intérprete on-line não permite o uso de eval em colchetes aninhados. Experimente o código da solução alternativa
JcQ5V4=J_CJ~Yml{meS<dhkUd_J)Y
e insira como uma lista nivelada como[4, 3, 5, 2, 1, 5, 4, 1, 3, 2, 1, 5, 2, 4, 3, 2, 1, 3, 5, 4, 3, 2, 4, 1, 5]
.(Obrigado a @isaacg, que ajudou a obter alguns bytes de golfe)
fonte
<
e>
são os operadores de fatia unilateral, para que:d0hk
possam ser transformados<dhk
.U
nas entradas de coleta é o mesmo queUl
, portanto,Uld
pode ser transformado emUd
.CJam,
2927 bytesEntrada como
Saída como
Como funciona
A idéia básica é fazer com que o código funcione ao longo das linhas e gire a grade no sentido anti-horário 4 vezes. Para contar as torres, estou levantando cada torre o máximo que não fizer uma "diferença visual" (ou seja, não a altere se estiver visível, ou puxe-a para a mesma altura da torre em frente a ) e, em seguida, estou contando alturas distintas.
fonte
APL, 44
Testado aqui.
fonte
J, 35 caracteres
Exemplo:
Experimente aqui.
fonte
Haskell, 113
fonte
Mathematica,
230.120.116.113110 bytesUso:
fonte
a[[y]][[x]]
éa[[y,x]]
. E o usoArray
pode ser menor queTable
.JavaScript,
335264256213Avalie no console JavaScript do navegador (usei o Firefox 34.0, não parece funcionar no Chrome 39 ??) Teste com:
Aqui está a encarnação atual do código não destruído - está ficando mais difícil de seguir:
Intencionalmente, não olhei para nenhuma das outras respostas, queria ver se eu mesmo poderia descobrir algo. Minha abordagem foi achatar as matrizes de entrada em uma matriz unidimensional e pré-calcular deslocamentos para as linhas de todas as quatro direções. Então usei shift à direita para testar se a próxima torre era falsa e, se era, então incrementava o contador para cada linha.
Espero que haja muitas maneiras de melhorar isso, talvez não pré-calcule as compensações, mas use algum tipo de estouro / módulo na matriz de entrada 1D? E talvez combine meus loops, fique mais funcional, desduplicado.
Todas as sugestões serão apreciadas!
Atualização # 1 : Progresso, nós temos a tecnologia! Consegui me livrar das compensações pré-calculadas e fazê-las alinhadas com os operadores ternários ligados. Também foi capaz de se livrar da minha declaração if e converter os loops for em whiles.
Atualização # 2 : Isso é bastante frustrante; nenhuma festa de pizza para mim. Eu imaginei que ficar funcional e usar a recursão reduziria muitos bytes, mas minhas primeiras tentativas acabaram sendo maiores em até 100 caracteres! Em desespero, eu comecei a usar as funções de flechas de gordura ES6 para realmente reduzi-las. Depois, substituí os operadores booleanos pelos aritméticos e remova parênteses, ponto e vírgula e espaços sempre que possível. Eu até parei de declarar meus vars e poluí o namespace global com meus símbolos locais. Sujo, sujo. Depois de todo esse esforço, superei a pontuação da Atualização # 1 em 8 caracteres, até 256. Blargh!
Se eu aplicasse as mesmas otimizações cruéis e truques do ES6 na minha função Atualização # 1, superaria essa pontuação por uma milha. Eu posso fazer uma atualização nº 3 apenas para ver como isso seria.
Atualização # 3 : Acontece que a abordagem recursiva da seta gorda tinha muito mais vida útil, eu só precisava trabalhar com a entrada bidimensional diretamente, em vez de achatá-la e melhorar a alavancagem dos escopos de fechamento. Reescrevi os cálculos de deslocamento da matriz interna duas vezes e obtive a mesma pontuação, portanto, essa abordagem pode estar quase esgotada!
fonte
Apenas Java
352350325 bytes ...Entrada como
43521 54132 15243 21354 32415
Saída como:
23145343211222233212
Recuado:
Quaisquer dicas seriam extremamente apreciadas!
fonte
for
loopsfor(;i<n;i++)
parafor(;++i<n;)
e inicializari
a-1
. Em seguida, use-os para fazer coisas. Você pode fazer o mesmo com o outro loop também.a[i].charAt(j)-'0'
vez da análise explícita. Isso também não requer delimitadores na entrada (torna o formato de entrada mais parecido com o formato de saída).for
-loops, você sempre pode inserir algo útil na parte "incremento de loop". Isso torna o código mais obscuro e remove um ponto e vírgula. Por exemplo:for(j=n;j-->0;System.out.print(c))
.Python 2 - 204 bytes
Este é provavelmente um golfe realmente ruim. Eu pensei que o problema era interessante, então decidi resolvê-lo sem olhar para a solução de mais ninguém. Enquanto escrevo esta frase, ainda não vi as respostas sobre essa pergunta. Eu não ficaria surpreso se alguém já tivesse feito um programa Python mais curto;)
Exemplo de E / S
Opcionalmente, você pode incluir espaço em branco na entrada. Praticamente em qualquer lugar, honestamente. Contanto que você puder
eval()
, funcionará.Explicação
A única parte interessante deste programa é a primeira linha. Ele define uma função
f(l)
que informa quantas torres podem ser vistas seguidas, e o restante do programa está apenas aplicando essa função em todas as posições possíveis.Quando chamado, ele encontra o comprimento de
l
e o salva em uma variáveln
. Em seguida, cria uma nova variávelk
com essa compreensão bastante monstruosa da lista:Não é tão ruim quando você o divide. Desde então
n==len(l)
, tudo antes doif
justo represental
. No entanto, usandoif
podemos remover alguns elementos da lista. Nós construímos uma lista com([0]+list(l))
, que é apenas "l
com um valor0
adicionado ao início" (ignore a chamada paralist()
, que está lá apenas porque às vezesl
é um gerador e precisamos garantir que seja realmente uma lista aqui).l[c]
só é colocado na lista final se for maior que([0]+list(l))[c]
. Isso faz duas coisas:l[c]
se tornac+1
. Estamos comparando efetivamente cada elemento ao elemento à esquerda dele. Se é maior, é visível. Caso contrário, ele será oculto e removido da lista.[0]+
absurdo e apenas em relaçãol[c]
al[c-1]
, Python iria comparar a primeira torre para o último (você pode indexar em uma lista a partir da extremidade-1
,-2
etc.), de modo que se a última torre era mais alto do que o primeiro, teríamos o resultado errado.Quando tudo estiver dito e feito,
l
contém um certo número de torres ek
cada uma delas que não é mais curta que seu vizinho imediato à esquerda. Se nenhum deles foi (por exemplo, paraf([1,2,3,4,5])
), entãol == k
. Sabemos que não há mais o que fazer e retornarn
(o comprimento da lista). Sel != k
isso significa que pelo menos uma das torres foi removida desta vez e pode haver mais o que fazer. Então, voltamosf(k)
. Deus, eu amo recursão. Curiosamente,f
sempre recursa um nível mais profundo do que o estritamente "necessário". Quando a lista que será retornada é gerada, a função não tem como saber disso a princípio.Quando comecei a escrever essa explicação, esse programa tinha 223 bytes. Ao explicar as coisas, percebi que havia maneiras de salvar personagens, então estou feliz por ter digitado isso! O maior exemplo é que
f(l)
foi originalmente implementado como um loop infinito que foi interrompido quando a computação foi concluída, antes que eu percebesse que a recursão funcionaria. Isso mostra que a primeira solução que você pensa nem sempre é a melhor. :)fonte
Matlab,
(123)(119)usado assim:
C #, até 354 ...
Abordagem diferente da usada pelo TheBestOne.
fonte
\n
vez de novas linhas, apenas as substituí por espaços, para que o código seja executado imediatamente quando alguém o estiver copiando. E eu me permiti apagar o últimoend
(que fecha a função, que não é necessário) o que economiza adicional de 4 caracteres, espero que era ok =)end
, porém, thx :)