Quartas-feiras Prime

22

Quartas-feiras Prime

Sua tarefa é contar o número de quartas-feiras que caem em um dia nobre do mês em um determinado ano. Por exemplo, 7-13-16é uma quarta-feira nobre. Para obter consistência, use o calendário gregoriano para todas as datas.

Entrada

A entrada para o seu programa / função será de um ano (por exemplo 2016) e é flexível. O ano será um número inteiro entre 1912 e 2233, inclusive.

Saída

A saída também é flexível e deve ser o número de quartas-feiras principais (por exemplo 18).

Pontuação

Este é o pelo que o código mais curto em bytes vence!

Casos de teste

entrada -> saída
--------------------
1912 -> 19
1914 -> 16
1984 -> 17
1996 -> 19
2063 -> 19
2150 -> 16
2199 - > 18
2233 -> 18

NonlinearFruit
fonte

Respostas:

7

MATL , 38 36 34 bytes

FT+"@llI$YO]q&:t8XO!s9\~)9#1$ZOZps

Experimente online! Ou verifique todos os casos de teste (leva alguns segundos).

Explicação

FT+     % Input year implicitly. Add [0 1] element-wise. Gives array with input year
        % and next year
"       % For each of those two years
  @     %   Push year
  ll    %   Push 1 twice. This indicates January 1.
  I$YO  %   Convert year, month, day to serial date number
]       % End for each. We now have the serial date number for January 1 of the input
        % year and that of the following year
q       % Subtract 1 to the latter, to yield December 31 of the input year
&:      % Inclusive range between those two numbers. This gives an array of serial date
        % numbers for the whole input year
t       % Push another copy of that array
8XO     % Convert to date string with format 8. This gives weekday as "Mon", "Tue" etc.
        % The result is a 3-column 2D char array, where each row is a day
!s      % Transpose, sum of each column. 'Wed' gives 288 (sum of ASCII codes)
9\~     % 288 gives 0 modulo 9, and is the only weekday to do so. So we compute modulo 9
        % and negate. This gives true for Wednesdays, false for the rest
)       % Apply as logical index into the array of serial date numbers
9#1$ZO  % Array of month numbers corresponding to those serial date numbers
Zp      % Array that contains true for prime numbers, false for the rest
s       % Sum of array. Display implicitly
Luis Mendo
fonte
Estou convencido de que o MATL não pode ser derrotado em desafios baseados em datas. Devemos criar DATL que seja otimizado ainda mais para lidar com desafios baseados em datas.
Suever
@Suever Haha, nice name
Luis Mendo
20

Python 2, 95 93 68 67 bytes

lambda y:0x10ea2c8dbb06c5619/5**((y+((y-22)/99-y/2002)*16)%28)%5+16

Obrigado a @Josay por jogar fora um byte!

Teste em Ideone .

Dennis
fonte
3
Você pode salvar 1 caractere em 0x10ea2c8dbb06c5619vez de 19501370182350951961.
SylvainD
Eu entendo a idéia, big_constant//5**long_expressionmas como você veio com essa constante e essa expressão? É loucura: D
Sherlock #
2
A constante é uma tabela de pesquisa simples usando dígitos da base 5, mas convertida na base 10, para que os dígitos sejam extraídos numericamente em vez de usar um índice de string. A expressão parece um calendário perpétuo para mim. (O problema seria fácil demais se fosse limitado a anos de 1901 a 2099, como as respostas se repetem a cada 28 anos nesse intervalo, então seria apenas um caso de pegar o mod 28 do ano e procurá-lo na tabela. )
Neil
13

Brain-Flak , 6588 , 2310 , 2308 , 2290 bytes

Para começar, não escrevi quase 100% deste programa, o que provavelmente é evidenciado pelo enorme tamanho do programa. A maior parte desse código foi escrita pelo meu próprio algoritmo de golfe Brain-Flak . Junto com um script python adicional que escrevi para avisá-lo na direção certa.

Experimente online!

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

Embora este programa seja bastante longo para o código de golfe, ele é decentemente curto para o Brain-Flak. Atualmente, o recorde mundial da divisão inteira é superior a 1000 bytes.

Explicação

O algoritmo é bastante simples. Como há um número limitado de anos disponíveis (321), ele simplesmente coloca as respostas na ordem inversa sob a entrada e usa um algoritmo de pesquisa para encontrar a resposta correta. Embora codificar todas as 321 possibilidades possa parecer bastante ineficiente com uma tarefa tão complexa como esta e uma linguagem tão esotérica quanto o cérebro, pode muito bem ser a melhor solução. (Eu pretendo descobrir na próxima semana).

Como a maioria dos 321 números tem cerca de 18 em média e diferem muito pouco de ano para ano, em vez de empurrar todos os números individualmente, eu empurro o primeiro ano (2233) normalmente e, em seguida, apenas duplico e altero um pouco o valor para cada ano depois de. Dessa forma, em vez de pagar para enviar ~ 18 por todos os 321 anos, pago apenas para enviar ~ 2 por ano.

Depois que todas as respostas foram enviadas, subtrai 1912 da entrada ({}[(((((((((()()()()())){}{}){}){}){}){}[()]){}){}){}]) (isso pode ser subótimo, reescrevi o otimizador para ignorar certos valores que eu acreditava não serem ideais, pois os números codificados são um processo superexponencial e sua execução até a conclusão pode ter alguns dias).

Em seguida, subtrai um do primeiro elemento e exibe o segundo elemento até o resultado chegar a zero {({}[()]<{}>)},.

Aparece o zero {}e todos os elementos abaixo do elemento superior ({}<{{}}>).

Assistente de Trigo
fonte
Qual é a abordagem geral dos números de golfe?
315 Neil
A idéia simples é que se você tiver um número com os fatores n e m, pressione n m-1 vezes e depois pressione m-1 vezes. O push inicial é avaliado como n e cada pop é avaliado como um n adicional, resultando em (1 + m-1) (n) que é o mesmo que mn. Isso é feito recursivamente, porque, para empurrar n, também precisamos jogar golfe. Como esse método não funciona bem para alguns números particularmente primos, também procuramos ao redor para ver se há um número mais eficiente por perto e, se sim, expressamos isso como a soma desse número e a diferença.
Assistente de Trigo
Entendo ... então, dados dois números ne mquais têm comprimentos ke l, presumo n+mque teriam comprimentos k+l? Que tal n*m?
Neil
n*mseria k+4m-4ou l+4n-4. Isso ocorre porque a multiplicação é codificada. Primeiro pressionamos os n m-1tempos. Para fazer isso, precisamos de ksímbolos para expressar ne 2m-2símbolos para expressar os empurrões (cada empurrão é de 2 símbolos). Então nós pop m-1vezes, custando-nos um adicional 2m-2(pops custam 2 símbolos também). Isso totaliza k+4m-4. também podemos multiplicar m*n(propriedade comutativa) para obterl+4n-4 . O resultado será o mais curto dos dois.
Assistente de trigo
1
Bem, se isso é verdade, +1custa 2, *2custa 4, *3custa 8, *4custa 12, o que é mais caro do que *2*2, portanto, não vale a pena (em números abaixo de 1000, encontrei apenas 10 que não usavam *2: 1, 2, 3 , 4, 5, 9, 15, 27, 45, 135). Para 1912, o melhor que eu podia fazer era ((((((1+1+1)*2+1)*2*2+1)*2+1)*2+1)*2+1)*2*2*2com um comprimento de 52.
Neil
7

Bash + utilitários comuns, 39

ncal $1|grep W|factor|egrep -c ': \S+$'

Toma o ano de entrada como um parâmetro de linha de comando. Normalmente envia mensagens como esta para STDERR - acho que isso é legal conforme esta meta-resposta :

factor: We is not a valid positive integer

Se você desejar suprimir explicitamente a saída STDERR, poderá fazer isso para uma pontuação de 43 :

ncal $1|grep W|factor 2>-|egrep -c ': \S+$'
Trauma Digital
fonte
Observe que isso pressupõe um código de idioma inglês ou C / POSIX. Não funciona tão bem gd_GB.utf8onde todos os nomes de dia abreviam Di.
Toby Speight
6

Oitava, 86 bytes

Isso não é rápido, de forma alguma. Mas esse não é realmente o objetivo de um código de golfe, é?

function r=p(y)r=0;for(i=698346:7:815953)d=datevec(i);r+=d(1)==y*isprime(d(3));end;end

A oitava pode rastrear datas por "número da data" - número de dias decorridos em que 1º de janeiro de 0 é o dia 1. Por essa medida, 3 de janeiro de 1912 (a primeira quarta-feira do nosso conjunto) é o dia 698.346. Comece por aí e percorra todos os 7 dias (todas as quartas-feiras) até o final de 2233 e adicione 1 se o ano for o ano de destino E o dia do mês for nobre.

dcsohl
fonte
5

Python 2.7, 166 , 165 , 150 bytes

from datetime import*
y=input()
d,c=date(y,1,1),0
while d.year==y:n=d.day;c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n));d+=timedelta(1)
print c

Certamente há espaço para melhorias aqui. Eu sou bastante novo no golfe em python. Isso usa odatetime módulo. Ele percorre todos os dias do ano, adicionando um a um acumulador se ele se encaixa no critério. Em seguida, imprime o resultado. A maior parte do trabalho pesado está no módulo, portanto o código pode ser bem pequeno.

Um byte economizado graças ao Morgan Thrapp e 15 bytes salvos pelo Pietu1998 .

Assistente de Trigo
fonte
1
Você pode salvar um byte alternando n%x==0para n%x<1.
23416 Morgan Thrapp
2
O -1não é necessário, pois rangeo índice final é exclusivo. Além disso, você pode converter filterpara um gerador. [0for x in range(2,n)if n%x<1]
PurkkaKoodari
Você poderia usar any(...)ou em all(...)vez de not filter(...).
Kennytm
1
Combinando comparações encadeadas e allvocê pode economizar um monte. c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n))
PurkkaKoodari
3

J, 44 bytes

+/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)

Acabei de descobrir que J tem construído para manipulação de datas.

Uso

Comandos extras são usados ​​para formatar várias entradas / saídas.

   f =: +/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)
   (,.f"0) 1912 1914 1984 1996 2063 2150 2199 2233
1912 19
1914 16
1984 17
1996 19
2063 19
2150 16
2199 18
2233 18

Explicação

+/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)  Input: year
                                       i.12   The range [0, ..., 11]
                              >:              Increment each to get the months [1, ..., 12]
                                    p:        Get the first 12 primes [2, ..., 37]
                                ,"0/          Make a table between each month and prime
                           ,/                 Join the rows
                       ,.&                    Prepend the year to each
                                              The date format is YYYY MM DD
            3=weekday                         Check if each date occurs on Wednesday
    valdate*                                  and is a valid date
+/@                                           Count the number of true values and return
milhas
fonte
1

PowerShell v3 +, 99 95 bytes

Abordagem da força bruta -

param($y)(1..12|%{$m=$_;2,3,5,7,11,13,17,19,23,29,31|?{(date "$m-$_-$y").DayofWeek-eq3}}).Count

Pega entrada $y, faz um loop de 1para 12, armazena o mês temporariamente em e $m, em seguida, faz um loop em todos os primos de 2para 31. Para cada um deles, construímos um Get-Datedia específico e, em seguida, selecionamos apenas aqueles com DayOfWeek -equal para 3(ou seja, quarta-feira). Encapsula que tudo em um parens para formular uma matriz e leva a .Countmesma.


Alternativamente, abordagem matemática -

PowerShell v3 +, 105 bytes

param($y)(16,19,18,20,16,18,19)[($a=(date "1-1-$y").DayOfWeek)]+(1,-3,0,1,2)[$y%5]*($a-in0,2,3,4)*!($y%4)

Acabará sendo apenas um fio de cabelo mais longo do que a abordagem da força bruta, mas eu o incluo aqui, pois pode ser benéfico para os outros.

Mais uma vez assume a entrada $ycomo o ano. Desta vez, estamos realizando estritamente operações matemáticas com base no primeiro dia do ano. Primeiro calculamos o dia da semana e os armazenamos $apara uso posterior. Isso indexa a primeira matriz, o que nos dá o número normalmente correto. Temos que acrescentar a isso um segundo índice, com base no potencial ano bissexto, seja domingo, terça, quarta ou quinta-feira, e com base no que é o ano.

Isso é baseado na seguinte observação. A primeira coluna é o dia da semana em 1º de janeiro e a segunda é a saída usual. A menos que o ano seja um dos números do meio, é o número em parênteses. A coluna final descreve como a indexação% 5 funciona.

Jan-1 -> #  ... Except if $y=       (then it's this number) | $y % 5 =
Sun   -> 16 ... 1928 1956 1984 etc. (17)                    |    3
Mon   -> 19
Tue   -> 18 ... 1924 1952 1980 etc. (20)                    |    4
Wed   -> 20 ... 1936 1964 1992 etc. (17)                    |    1
Thur  -> 16 ... 1920 1948 1976 etc. (17)                    |    0
Fri   -> 18
Sat   -> 19

Nota: Ambos assumem que en-usé a configuração atual do PowerShell para informações de cultura / data. A formatação e o DayOfWeeknúmero da data podem precisar ser ajustados de acordo com outras variantes de cultura.

AdmBorkBork
fonte
1

Ruby, 83 + 15 ( -rdate -rprimesinalizadores) = 98 bytes

Experimente online! (Os módulos importados são incorporados porque idk, se eu puder usar sinalizadores em repl.it)

->y{k=0;Prime.each(31){|d|k+=(1..12).count{|m|Date.new(y,m,d).wday==3 rescue p}};k}
Value Ink
fonte
1

JavaScript ES6, 187 182 181 179 bytes

179 Trocado em um loop for pelo loop while

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);for(;a()<=y;c())N+=y-a()?0:-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());return N}

181 Compactou o ternário

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<=y){N+=y-a()?0:-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());c()}return N}

182 Combinaram os dois loops

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<=y){N+=a()==y?-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b()):0;c()}return N}

187

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<y)c();for(;a()==y;c())N+=-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());return N}
Pandacoder
fonte
Acho que isso não conta, pois você deu a primeira quarta-feira inicial do ano específico, neste exemplo. Estados desafio do OP de que necessita o ano como o único parâmetro ... Grande esforço até agora embora ...
Wally West
"A entrada para o seu programa / função será de um ano" - mas o que você está apontando não é isso. Uso a primeira quarta-feira de 1912 como uma semente porque é ou é antes de todas as outras quartas-feiras no período dado pelo OP, mas eu poderia facilmente usar qualquer quarta-feira arbitrária de 1911 ou antes para semear também. A entrada para minha função ainda é de um ano, e a função ainda calcula o número de quartas-feiras principais em qualquer ano no período sugerido pelo OP, portanto, não tenho certeza de como isso não se encaixa no desafio.
Pandacoder
Ah, desculpas ... Eu não sabia que no início você está usando isso como um componente de semeadura ... grandes ideias ... Especialmente considerando sua solução bate meu por cerca de 30 ..;)
Wally West
1
Obrigado. Eu me inspirei na implementação Brain-Flak de Eamon Olive, que na verdade tem todas as respostas pré-programadas, de acordo com sua explicação.
Pandacoder
1

Lote, 248 bytes

@set/ad=0,l=1,n=20
@for /l %%i in (1913,1,%1)do @set/ad=(d+l+1)%%7,l=!(%%i%%4)-!(%%i%%100)+!(%%i%%400)
@goto %l%%d%
:03
:06
@set/an-=1
:12
:13
:16
@set/an-=1
:01
:04
:14
@set/an-=1
:00
:05
:10
:15
@set/an-=1
:02
:11
@echo %n%

Explicação: dé o dia da semana, com 0Segunda-feira, que é convenientemente 1º de janeiro de 1912. lé um sinalizador para saber se o ano é um ano bissexto, 1para 1912. Passamos de 1913 para o ano de entrada, atualizando o dia de semana e recalculando a bandeira do ano bissexto à medida que avançamos. Finalmente, usamos a bandeira do ano bissexto e o dia da semana para indexar o que é efetivamente uma declaração de grande chave para determinar no número de quartas-feiras principais. Definir npara 20 e diminuí-lo com queda é mais barato do que usar a lógica de controle de fluxo, mas o resultado é que, se o dia 1º de janeiro de um ano sem salto for quinta-feira ou domingo, haverá 16 quartas-feiras principais e assim por diante nos outros casos .

Neil
fonte
1

JavaScript ES6 206 203 199 197 195 183 182 179

Não é o mais curto, mas o melhor que posso fazer por enquanto ... Sugestões de golfe são bem-vindas ...

p=n=>--d-1?n%d&&p(n):1;v=Date;D=(x,y)=>new v(x.setDate(x.getDate()-y));W=a=>eval('for(Z=0,z=D(w=new v(a,11,31),(w.getDay()+4)%7);z>new v(a,0,1);)Z+=~~p(d=z.getDate()),z=D(z,7);Z')

Alterar:

  1. alterando o componente ternário de: 3>=x?3-x:10-xpara 6-(x+10)%7, salvando: 3 Alterações nos locais da declaração;
  2. mesclado x=w.getDay();z=D(w,6-(x+10)%7)a z=D(w,6-(w.getDay()+10)%7), salvando: 4
  3. mudou Z=0de forloop para declaração de Data e empurrou z=D(w,6-(x+10)%7)para forloop para arrumar, economizando: 2
  4. w=new Date(a,Z=0,1)declaração deslocada em forloop, mesclando com a wdeclaração existente , salvando: 2
  5. reescrevendo a função de localização principal em uma função de teste principal, economizando: 12
  6. alterar +!!para ~~reduzir e ainda converter p(d=1)de NaNpara 0, permitindo que a função Prime Test ainda funcione, economizando: 1
  7. Todas as funções extras foram removidas da função de chamada principal W, forloop redefinido - retornando a partir de 31 de dezembro, escrevendo o Dateobjeto como uma variável separada e depois reescrevendo o forloop na evalchamada; salvando 3.

@PandaCoder, estou alcançando você, companheiro!

WallyWest
fonte
1

R, 149 147 bytes

y=function(x){s=strftime;b=ISOdate
a=seq(b(x,1,1),t=b(x,12,31),b='d')
length(a[s(a,'%u')==3&trimws(s(a,'%e'))%in%c(2,3,5,7,11,13,17,19,23,29,31)])}

Teste em Ideone .

chrki
fonte
0

Groovy, 126

O Groovy não tem validação de número primo, teve que criar isso também.

{n->p={x->x<3||(2..Math.sqrt(x)).every{x%it}};(new Date("1/1/$n")..new Date("12/31/$n")).collect{it[7]==4&&p(it[5])?it:0}-[0]}
Urna de polvo mágico
fonte