Seu desafio é escrever um programa que, dado um ano, produz o número de "sexta-feira 13" nele.
Regras e detalhes:
- Você pode receber informações via
STDIN
ou como um argumento passado para o seu programa. - Você deve enviar o resultado para
STDOUT
. - Você pode assumir que a entrada será um ano válido e não antecede o calendário gregoriano (comportamento indefinido é permitido nesses casos).
- Bibliotecas de calendário / data são permitidas.
Este é um código de golfe , portanto o código mais curto (em bytes) vence.
Respostas:
APL (Dyalog APL) com cal de dfns , 29 bytes
Experimente online!
⍳ 12
os inteiros de um a doze⎕ ,¨
pegue a entrada numérica e preceda cada um dos doze números{
…}¨
Em cada um dos pares, aplique a função…cal⍵
obter um calendário para esse ano-mês2 ↓
soltar duas linhas (legenda e dias)⍉
transpor (para que possamos endereçar colunas em vez de linhas)¯5 ↑
pegue os cinco últimos (dois dígitos para cada sexta-feira e sábado, mais um espaço)3 ↑
pegue os dois primeiros (dois dígitos para sexta-feira mais um espaço)⍉
transpor (para obtermos a ordem de leitura),
andar⍎
executar como expressão APL (fornece uma lista das datas das sextas-feiras)13 ∊
treze é um membro dessa lista?+/
somar os 12 booleanosUsando o algoritmo do @ Wrzlprmft , podemos fazê-lo sem bibliotecas de 53 bytes:
-∘0 1
subtrair zero e um400 100 4 ∘.|
tabela restante de divisão para os dois anos (transversalmente) dividida por esses números (abaixo)0 ≠.=
"produto" interno com 0, mas usando ≠ e = em vez de +. ×⊢ ,
preceder o ano do argumento não modificado2 3 ¯1 +.×
produto interno com esses números14 |
divisão restante quando dividido por catorze'21232211321211' ⌷⍨
indexar nessa cadeiafonte
Mathematica
49 46 45 4442Como uma função pura : 42 caracteres
Exemplo
Como uma função nomeada : 44 caracteres
Exemplos
fonte
f=DayName@{#,m,6}~Table~{m,12}~Count~Friday&
Ruby,
49 48 4746Edit: Raspou um personagem voltando uma semana, graças a Jan, e outro mudando de Time.new para Time.gm
Edit: À custa de ofuscá-lo um pouco mais, posso chegar a 46 com
fonte
Time.gm(m,i).wday<1
. Além disso, não sei por que você está nomeando a função.Powershell,
6863585250Obrigado Iszi pela dica.
Usando o fato de que se o primeiro dia do mês for domingo, o dia 13 será sexta-feira.
Eu também tentei:
mas não é o mesmo
$args
dentro do bloco de scripts.fonte
$n
por$args
no loop e você pode prescindir$n=read-host;
totalmente. Salva 8. Remova @, como mencionado acima, e você$args
para$input
, alimentando assim o ano a partir do gasoduto, e o script será executado, mas ele sempre envia 3.R
767257fonte
"%a %d")=="Fri 13"
com"%w%d)=="513")
usando dow como um número, e remover os espaços.seq
único no mês seja realmente mais curto aqui!sum(format(as.Date(paste(scan(),1:12,13,sep="-")),"%w%d")=="513")
tem apenas 65 caracteres!<
coagiria um caractere a um número inteiro. Bom truque!Python2.7
9086Segunda-feira, dia 9, pode não ter o mesmo toque, mas funciona tão bem quanto.
Edit: Um ano e meio para perceber que
date
é menor quedatetime
:)fonte
from datetime import*
f=lambda y:sum([date(y,m,13).weekday()==4 for m in range(1,13)])
.... Mesmo tamanho de solução com a importação (86 bytes).Não usando nenhuma biblioteca ou função de data interna:
Golfscript - 51
Python -
8279Essencialmente o mesmo algoritmo.
Usando esse truque , você pode jogar ainda mais:
fonte
C
301+287Não é a resposta mais curta, mas não usa bibliotecas.
fonte
static char GetNumberOfFriday13s(int year) { const string perpetualCalendar = "1221212213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213112213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122221122213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122221122131"; return perpetualCalendar[year % 400];
. Não vai funcionar por anos negativos.v[0]
deveria serv[1]
. Você também pode jogar golfe um pouco; considere usarstrcat
, armazenar caracteres para imprimir diretamentea[]
e subtrair constantes numéricas em vez de constantes de caracteres. :)main(int x,char**v){char p[400],*a[]={"1221212213113213","2131222","21122131","1222","112213113","122223113","122221122"},*b="adcadcadcaebcadcadcafbcadcadcagbcadcadcadc";*p=0;for(;*b;b++)strcat(p,a[*b-97]);putchar(p[atoi(v[1])%400]);}
(215 caracteres)C (
151145137131130 caracteres)Estou surpreso ao ver que há apenas uma outra solução que não usa ferramentas de calendário internas. Aqui está uma abordagem matemática (altamente ofuscada), também em C:
(O acima é compilado no GCC sem erros)
Solução alternativa: C (287-> 215 caracteres)
Gostei bastante da solução de Williham Totland e de seu uso de compressão. Corrigi dois pequenos bugs e alterei o código para diminuir seu comprimento:
fonte
PHP, 82
<?for($i=1,$c=0;$i<13;$i++)$c+=(date("N",mktime(0,0,0,$i,1,$argv[1]))==7);echo $c;
Baseado em
"Qualquer mês que começa no domingo contém uma sexta-feira 13 e há pelo menos uma sexta-feira 13 em cada ano civil".
De http://en.wikipedia.org/wiki/Friday_the_13th
fonte
festança
4736Obrigado @DigitalTrauma por salvar 10 caracteres usando
seq
o início padrão para1
.(Versão anterior usando
echo
apresentar um bug por causa da linha vazia quando<(echo $1-{1..12}-6$'\n')
. Portanto, esta função funcionou bem até hoje é uma sexta-feira.Vamos ver:
Is é dependente da localidade ; se, se não funcionar, pode ser necessário
ou
Em uma função; +7 -> 43
Bônus: +78 -> 121
A partir daí, se minha função se tornar:
ou
fonte
C
. Mas há um erro ...%s\\n
seq
para soltar 8 caracteres:date -f<(seq -f$1-%g-6 1 12)|grep -c ^F
seq -f$1-%g-6 12|date -f-|grep -c ^F
JavaScript, 70
fonte
,b,c
da declaração da função (! Que é OK para vazamento de vars para o golfe), também comob
é moldado como umNumber
possível+=
resultado de teste em vez do&&b++
:b+=/^F/.test(new Date(a,c,6))
. No entanto, você pode salvar outro byte usando!new Date(a,c,1).getDay()
(isso funciona porquegetDay
retorna 0 para domingo e, se o dia 13 for sexta-feira, o primeiro dia será domingo) em vez dotest
que, em conjunto, você deverá economizar 7 bytes!k
64 caracteres
Lê a partir de stdin
fonte
Lisp comum (CLISP), 149
fonte
C #
1101019392C # Linq 88
Agradeço a Jeppe Stig Nielsen pelo linq e pela sugestão de verificar o domingo no dia 8.
Obrigado a Danko Durbić por sugerir em
>
vez de==
.fonte
c+=(int)new DateTime(y,i,13).DayOfWeek==5?1:0;
, use o equivalentec+=new DateTime(y,i,8).DayOfWeek==0?1:0;
. O truque é subtrair5
, porque então você pode se livrar do elencoint
e também o número8
tem um dígito a menos que o número13
. Domingo o oitavo!int g(int y){return Enumerable.Range(1,12).Count(m=>new DateTime(y,m,8).DayOfWeek==0);}
. Claro que como lambda é issoy=>Enumerable.Range(1,12).Count(m=>new DateTime(y,m,8).DayOfWeek==0)
..DayOfWeek<1
.c#
resposta, mas não sei ao certo como aplicá-lalinq
.DayOfWeek
com nenhum outro número inteiro que não0
-error CS0019: Operator '<' cannot be applied to operands of type 'System.DayOfWeek' and 'int'
.PHP, 55 bytes
Corra com
echo <year> | php -nR '<code>'
.Basicamente, o mesmo que Oleg tentou e Damir Kasipovic , apenas com um golfe melhor:
todo mês que começa com um domingo, tem uma sexta-feira 13.
Então, percorro os meses e conto os primeiros dias que são domingos.
demolir
fonte
K, 42
.
fonte
Bash (
5247 caracteres)fonte
Rebol, 63
Exemplo de uso no console Rebol:
A solução alternativa que coleta toda a sexta-feira 13 em determinado ano é:
fonte
Bash e Sed, 39
ncal
imprime um calendário para o ano especificado com os dias da semana à esquerda.sed
com uma/g
bandeira apaga todos os 13s com novas linhasgrep -c
conta as linhas que começam com "2" (20 sempre segue 13)Obrigado a @DigitalTrauma por encontrar um bug na minha versão antiga e propor uma solução!
fonte
ncal $1|sed /F/s/13/\\n/g|grep -c ^\ 2
Scala,
7668 caracteresEm 78 caracteres:
def f(y:Int)=0 to 11 count(new java.util.GregorianCalendar(y,_,6).get(7)==6)
Nada fora do comum, exceto pelo uso de números mágicos para
DAY_OF_WEEK = 7
eFRIDAY = 6
.Versão de 68 caracteres:
def f(y:Int)=0 to 11 count(new java.util.Date(y-1900,_,6).getDay==5)
Sim, o Java alterou os valores das constantes do dia da semana entre as APIs.
fonte
new java.util.GregorianCalendar
tenha que ser tão longo :(Python 195/204
Funciona apenas para anos anteriores, porque
monthdatescalendar
retorna um calendário para o ano especificado até agora . Eu acho que ainda há muito potencial de otimização :).Outra solução, funciona para todas as datas, mas não é menor:
fonte
Perl 6,
5553Resposta antiga:
fonte
Python (v2) 120
fonte
Perl + lib POSIX 55
Com a idéia de não procurar,
13th
mas primeiro, e comosunday
é0
isso, vamos salvar 3 caracteres! Obrigado @ Iszi e Danko Durbić!Poderia calcular 2010 a 2017 (por exemplo) desta maneira:
(Ok, não há nova linha , mas isso não foi solicitado;)
Post antigo: 63
Em ação:
fonte
Em Smalltalk (sabor Squeak / Pharo), implemente esse método em Inteiro ( 86 caracteres)
Em seguida, usá-lo como este:
2014countFriday13
.Claro, poderíamos usar um nome mais curto, mas não seria Smalltalk
fonte
Muitos bytes :(
Eu tentei uma solução que não faz uso de nenhuma biblioteca de datas.
Encontrei uma solução bem legal (se assim posso dizer). Infelizmente, não posso obtê-lo mais curto do que isso, o que realmente me incomoda, porque parece que deveria haver uma maneira melhor.
A solução depende desse algoritmo, que possui apenas 44 bytes. Infelizmente, preciso de mais 100 bytes para embrulhá-lo bem ...
Saída através do código de retorno (em C ++, usando
cout
ouprintf
ou algo assim requer outra#include
, o que explodiria ainda mais a solução).Programa de driver / teste:
Saída do programa do driver:
fonte
($m<3?$y--:$y-2)+3
em vez ded=13,
,d+=m<3?y--:y-2,
ed+4
deve funcionar bem e economiza muito.+5
em vez de+3
e-5
deve funcionar também e economiza 2 bytes.for(m=0;++m<13;)
salva um byte. Moverm=0
para o cabeçote da função salva outro byte; e mover()%7||++f
para a cabeça do laço salva outra. Diminua de 149 para 136 bytes.Clojure,
207187 bytes-20 bytes, livrando-se do
import
espaço em branco que perdi.A partir de 1º de janeiro do ano em questão, ele volta todos os dias. Se o dia for sexta-feira 13, aumentará a contagem. Ele continua em loop até atingir o próximo ano.
fonte
PHP, sem builtins, 81 bytes
Corra com
echo <year> | php -nR '<code>'
.demolir
Os dias da semana se repetem a cada 400 anos.
Nos resultados de 1600 a 1999 (por exemplo), há um período de 28 períodos com apenas três lacunas:
Depois de ajustar o ano para essas lacunas, podemos obter o resultado com um simples hash:
Não é curto (95 bytes), mas bonito. E nós podemos jogar golfe
fonte
for(;++$m<13;23*$m/9+($m<3?$y--:$y-2)+5+$y/4-$y/100+$y/400)%7?:$f++)$y=$argn;echo$f;
Japonês
-x
, 10 bytesTente
fonte