Fingir a previsão

15

O novo supercomputador de previsão do tempo chegou e não funciona.

Enquanto isso, seu chefe quer que você compre algum técnico fingindo os mapas diários de vento.

Sua tarefa é desenhar uma grade de setas representando a direção do vento.

A grade é:

  • composto de 15px azulejos quadrados
  • 8 peças por 8 peças
  • Total quadrado de 120px
  • 000 antecedentes

Cada bloco de grade possui 8 orientações em potencial, representando a direção do vento:

  1. Norte
  2. Nordeste
  3. Leste
  4. Sudeste
  5. Sul
  6. Sudoeste
  7. Oeste
  8. Noroeste

Qual deve ser representado como segue:

N N NE NE E E SE SE S S SW SW W W NWNW

Os mapas devem variar gradualmente , para serem críveis.

Isso significa que cada bloco pode diferir apenas do seu vizinho em uma etapa. Especificamente:

  • Um bloco pode diferir apenas em um incremento ou decremento de cada um dos quatro blocos adjacentes. (ou 3 para ladrilhos laterais, 2 para ladrilhos de canto).
  • por exemplo, uma peça com o vizinho E pode ser NE, E ou SE (assumindo que esteja de acordo com os outros vizinhos).
  • As orientações podem voltar, ou seja, N -> NW e NW -> N.

Para ilustrar, o seguinte mapa é válido:

NW  N NE NE NE NE NE NE 
 N NE NE NE NE NE NE  E 
NE NE NE NE NE NE  E SE 
 E NE NE NE NE  E SE  S 
SE  E  E  E  E SE  S SE 
 S SE SE SE SE  S SE  E 
SW  S  S  S  S SE  E NE 
SW SW  S  S SE  E NE  N 

Os mapas devem ser exclusivos , não gere o mesmo mapa para entradas diferentes.

  • A entrada é um número inteiro correspondente aos dias entre agora e sua previsão (por exemplo, 1 é a previsão de amanhã, 365 é o ano).
  • Saída é o mapa como uma imagem.
  • A saída deve ser reproduzível, a mesma entrada sempre dará a mesma saída
  • Você deve fornecer mapas exclusivos por pelo menos 8 anos - ou seja, nenhuma saída idêntica para qualquer entrada entre 1 e 2920 (estou ignorando os anos bissextos).
  • Não há saída definida para nenhuma entrada maior que 2920.

O envio vencedor produzirá mapas válidos (até o dia 2920) com o menor número de bytes de código-fonte.

jsh
fonte
Qual é a entrada máxima que precisa ser manipulada? Existe alguma restrição sobre, por exemplo, as previsões de duas maneiras consecutivas que também devem diferir apenas por um valor máximo?
Ingo Bürk
A entrada máxima que precisa ser manipulada é 2920 . Não há nenhuma restrição em previsões consecutivos (exceto que eles devem ser exclusivos)
jsh
Desculpe, devo ter esquecido o último ponto. :)
Ingo Bürk
8
Um pouco fora do assunto: mostrei isso a um amigo que é meteorologista e ele me disse que alguns desses aplicativos climáticos que você pode obter não são muito melhores do que o que estamos fazendo aqui, pois aparentemente eles apenas pegam os dados climáticos gratuitos do grandes aeroportos e interpolá-los, na maioria das vezes essas interpolações são péssimas.
flawr
2
"O novo supercomputador de previsão do tempo chegou e não funciona". Envie para o International Journal of Climate Science. Será par para o curso. : P
COTO

Respostas:

4

BBC Basic, 83 caracteres ASCII, tamanho de arquivo tokenised 72

Faça o download do emulador em http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

  INPUTn:VDU23,48,516;543;4;0;23,49,783;5,9;0;0:WIDTH8FORi=1TO64PRINT;1ANDn;:n/=2NEXT

Esta é basicamente uma porta do conceito de Martin, mas a implementação no BBC basic é muito diferente. Eu reprogramei a fonte dos números 0e 1depois os dígitos binários nem ordem inversa.

Código não destruído está abaixo. No básico da BBC, você pode imprimir caracteres ASCII individuais usando o VDUcomando, mas o idioma possui uma série de códigos específicos da máquina, semelhantes às seqüências de escape, mas começando com caracteres não imprimíveis. Para reprogramar a fonte, começamos com ASCII 23. Normalmente, são utilizados valores de 8 bits, mas se você usar um ponto-e-vírgula como um separador em vez de uma vírgula, serão necessários valores endian pequenos de 16 bits (conforme usado na versão em golf).

  INPUTn
  VDU23,48,4,2,31,2,4,0,0,0         :REM redefine font for "0" as an east facing arrow, with an 8x8 bitmap
  VDU23,49,15,3,5,9,0,0,0,0         :REM redefine font for "1" as a northeast facing arrow, with an 8x8 bitmap
  WIDTH8                            :REM set print width to 8 characters
  FORi=1TO64PRINT;1ANDn;:n/=2:NEXT  :REM print the binary digits of n in reverse order from least significant to most significant.

Resultado

Para os números de 0 a 7. Observe que a fonte não é redefinida no final do programa; portanto, os números 0 e 1 aparecem como setas nos dois primeiros exemplos. insira a descrição da imagem aqui

Level River St
fonte
Boa ideia! :) Mas os azulejos são 15x15?
Martin Ender
@ MartinBüttner A BBC basic permite redefinir uma fonte em uma grade 8x8. Para manter os números pequenos, eu fiz a menor seta leste reconhecível (5x5 espremida no canto superior direito da grade) e fiz a seta nordeste mais parecida. No modo de tela usado aqui, a definição tem uma correspondência 1: 1 com pixels (e deixa um amplo espaço entre as linhas), mas eu dobrei o tamanho da grade no Windows Paint para obter uma imagem de tamanho melhor no SE. Alguns dos outros modos de tela no básico da BBC têm mais de 1 pixel por elemento de grade, e os caracteres definidos pelo usuário são visivelmente mais granulados que a fonte comum.
Level River St
23

Matlab (182 *)

Supõe-se que a entrada esteja armazenada n. Ao olhar para o algoritmo, não é certo que os resultados sejam únicos, mas verifiquei se n=1 upto 3000eles são únicos e atendem às regras. Basicamente, apenas uso números complexos do círculo unitário e os "suavizo" por conv2 com um filtro gaussiano. Depois disso, eles são arredondados para as 8 direções possíveis.

* Não sei como dimensionar a saída para um determinado número de pixels, de modo que isso deve ser feito manualmente = /

EDIT: Acabei de descobrir que há casos em que meu programa de verificação não reconhece soluções erradas (alterações em mais de uma etapa), mas estou tentando encontrar outra solução.

Entrada:

n = 1

Código:

rand('seed',0);
for x=1:n
    b = exp(1i*rand(8)*2*pi);
end
for k=1:12
    b = conv2(b,[1,2,1]'*[1,2,1],'same');b=b./abs(b);
end
c = exp(1i*round(angle(b)*4/pi)*pi/4)/3;
quiver(real(c),imag(c));

campo de vetor

flawr
fonte
O que você quer dizer com "dimensionar a saída para um determinado número de pixels", dimensionar as setas ou a imagem?
krs013
@ krs013 Quero dizer, dimensionar a imagem inteira, ainda não descobri como fazer isso, de modo que ela tenha, por exemplo, uma largura de exatamente 8 * 16 pixels.
flawr
15

Mathematica, 116 115 bytes

f@n_:=Graphics[Array[(d=n~BitGet~#;Arrow@{1+{w=15#~Mod~8+6.5d,h=15Floor[#/8]},14+{w-13d,h}})&,64,0],ImageSize->120]

Suponho que um bom cavalo nunca pula mais alto do que o necessário. As grades 2920 diferentes são muito facilmente obtidas com o uso de apenas duas direções (estou usando Ne NE), o que torna trivial a satisfação da regra de continuidade. Estou simplesmente escolhendo entre N e NE com base nos bits de n, então isso realmente produzirá 2 64 mapas de vento diferentes.

Aqui estão os dez primeiros mapas:

insira a descrição da imagem aqui

PS: Minha idéia original era enumerar todas as 8 4 combinações para os 4 cantos e interpolar "linearmente" o resto da grade. Provavelmente isso resultaria em mapas mais agradáveis, mas, afinal, este é um código de golfe, então fui com o que atende aos requisitos mínimos.

Martin Ender
fonte
Eu deveria ter pedido 2 ^ 64 + 1 grades. :)
jsh
@ jsh Eu tinha oito opções para duas direções adjacentes. Isso tornaria o código um pouco mais longo, mas ainda assim seria fácil e permitiria 2 ^ 67 grades únicas. Mas não se preocupe, acho que ainda é um bom código de golfe - fazer golfe com saída gráfica é difícil (devido à objetividade necessária) e acho que você fez um bom trabalho com ele.
Martin Ender
Gosto da ideia da interpolação, mas como você teria interpolado quando cada um dos quatro cantos apontaria para o centro?
flawr
4
@ MartinBüttner: Embora isso atenda tecnicamente às especificações, parece contrário ao espírito do desafio, que é tornar o mapa confiável. Apenas uma observação.
COTO 24/09
2
@COTO É verdade, mas também é um código de golfe e não um concurso de popularidade, e "credibilidade" não é um critério objetivo de validade.
Martin Ender
5

PHP 5.4, 549 bytes

Um pouco prejudicado pela necessidade de definir setas como gráficos, aqui está o meu código PHP:

<? $i=$argv[1];$p="R0lGODdhBQAFAIAAAP///wAAACwAAAAABQAFAAAC";$a=[$p."BwRiicGsDwoAOw",$p."CEQeoLfmlhQoADs",$p."CARiF8hnmGABADs",$p."CIwDBouYvGIoADs",$p."BwRil8Gs+QoAOw",$p."CIQRYcqrnkABADs",$p."CARihscYn1YBADs",$p."CAx+Bmq6HWIBADs"];$c=[$i&7,$i>>3&7,$i>>6&7,$i>>9];$m=imagecreate(120,120);imagecolorallocate($m,255,255,255);foreach($a as$_)$z[]=imagecreatefromstring(base64_decode($_));for($y=0;$y<8;$y++)for($x=0;$x<8;$x++)imagecopy($m,$z[($c[0]*(7-$x)*(7-$y)+$c[1]*$x*(7-$y)+$c[2]*(7-$x)*$y+$c[3]*$x*$y)/49%8],$x*15+5,$y*15+5,0,0,5,5);imagepng($m);

Recebe seu argumento da linha de comando, como:

php windmap.php 123

Esta solução usará a entrada como a definição dos quatro cantos. O restante do mapa será interpolado suavemente entre valores. Ele definiu resultados para todos os valores de 0 a 4095, um total geral de ~ 11,25 anos de previsão falsa, que deve ser mais do que suficiente para corrigir o software climático!

Aqui está um GIF de todos os resultados:

Ar quente!

E um ZIP contendo cada mapa pode ser baixado aqui

(Nota: meu domínio expirou recentemente porque não estava prestando atenção. Renovei-o, mas a imagem e o link acima podem não funcionar até que o DNS seja atualizado)

Não qualificado:

<?php
$input = $argv[1];
$prefix = "R0lGODdhBQAFAIAAAP///wAAACwAAAAABQAFAAAC";
$arrows = [
    $prefix."BwRiicGsDwoAOw", // E
    $prefix."CEQeoLfmlhQoADs", // NE
    $prefix."CARiF8hnmGABADs", // N
    $prefix."CIwDBouYvGIoADs", // NW
    $prefix."BwRil8Gs+QoAOw", // W
    $prefix."CIQRYcqrnkABADs", // SW
    $prefix."CARihscYn1YBADs", // S
    $prefix."CAx+Bmq6HWIBADs", // SE
];
$points = [
    $input & 7,
    $input >> 3 & 7,
    $input >> 6 & 7,
    $input >> 9 // input beyond 0o7777 (4095) will be undefined due to lack of & 7 here
];
$img = imagecreate(120,120);
imagecolorallocate($img,255,255,255);
$arrowimgs = [];
foreach($arrows as $src) {
    $arrowimgs[] = imagecreatefromstring(base64_decode($src));
}
for($y=0; $y<8; $y++) {
    for($x=0; $x<8; $x++) {
        $point = (
              $points[0] * (7-$x)/7 * (7-$y)/7
            + $points[1] *   $x  /7 * (7-$y)/7
            + $points[2] * (7-$x)/7 *   $y  /7
            + $points[3] *   $x  /7 *   $y  /7
        ) % 8;
        imagecopy($img,$arrowimgs[$point],$x*15+5,$y*15+5,0,0,5,5);
    }
}
imagepng($img,"out.png");
Niet, o Escuro Absol
fonte
Como funciona a interpolação?
flawr
@flawr Faz uma aproximação da distância de cada canto e usa isso como um peso para quanto o valor desse canto deve afetar o valor do ponto atual.
Niet the Dark Absol
Mas, neste caso, todas as flechas devem apontar para o meio no quadro 1647? tinyurl.com/o7z9grl
flawr 25/09/14
1
@flawr Olhe para baixo na coluna da esquerda para ver como ela está "interpolando" de 7 (SE) para 1 (NE), passando por todos os valores 6, 5, 4, 3, 2 ... em oposição aos menores "7, 0, 1 "que você pode esperar. O algoritmo não é sofisticado o suficiente para interpolar com rotação como essa.
Niet the Dark Absol
Ah, foi assim que você resolveu! Isso é realmente bom, já que a interposição com '7,0,1' resultaria em um campo de seta inválido =) +1 para os gráficos de seta!
flawr