Avançar Feliz Ano Novo, 2016!


40

Sua entrada será um número inteiro entre 1970 e 2090 (inclusive), representando um ano. Seu programa deve produzir o próximo ano em que o dia de ano novo cai no mesmo dia da semana que o ano de entrada.

Casos de teste:

Abaixo estão as entradas e saídas de amostra

2001 => 2007
2047 => 2058
2014 => 2020
1970 => 1976
1971 => 1982
1977 => 1983
2006 => 2012

Bônus de 20%: Saída no dia da semana do Ano Novo

2001 => 2007 (Mon)
2047 => 2058 (Tue)
2014 => 2020 (Wed)
1970 => 1976 (Thu)
1971 => 1982 (Fri)
1977 => 1983 (Sat)
2006 => 2012 (Sun)

30% Bonus: SaídaAdvance Happy New Year, <year>

2010 => Advance Happy New Year, 2016

Bônus de 50%: faça os dois bônus acima

2010 => Advance Happy New Year, 2016 (Fri)

Escreva um programa que leia a entrada de STDIN ou aceite argumentos de linha de comando ou uma função que aceite um argumento.

Nota: Adicione um link para testar seu código, se possível.

Entre os melhores:


6
Sinto que cada desafio de uma data exige o cálculo dos anos bissextos como um subproblema, e está ficando obsoleto.
Xnor

Relacionado: esta questão .
Addison Crump

@xnor Se não fosse esse o caso, teria sido apenas um +7.
Ou

@EriktheGolfer Não. Quando escrevi esse comentário, minha resposta foi a aceita.
Dennis

Respostas:


1

Geléia, 9 bytes

%4*3%7+5+

Essa é uma cadeia monádica que recebe como argumento um argumento inteiro da linha de comando. Ele usa meu (x+5+(x%4)**3%7)algoritmo.

Experimente aqui . Embora essa seja a versão atual do Jelly, ela também funciona nesta versão , que antecede o desafio. (Obrigado @Dennis!)


Isso é incrível! Posso confirmar que funciona com esta revisão do intérprete Jelly, que antecede o desafio.
Dennis

31

Mathematica, 45 37 27 24 bytes

#+5[6,6,11][[#~Mod~4]]&

Melhorias graças a @ MartinBüttner (10 bytes) e @ChipHurst (mais 3 bytes).


7
Uau. Ninguém parece ter notado esse padrão, mas funciona.
Lynn

4
Aqui está uma versão um pouco mais curta:#+5[6,6,11][[#~Mod~4]]&
Chip Hurst

@ChipHurst muito inteligente com 5[6, 6, 11][[0]]:)
martin

18

CJam, 21 12 11 bytes

{_9587Cb=+}

O @martin encontrou um método muito simples!

Experimente aqui .

EDIT: Obrigado, Dennis!


11
@Mauris Você poderia adicionar uma explicação?
Vasu Adari

@ Vasu: Este código é uma função anônima que implementa o mesmo 5 6 6 11truque usado em outras respostas, mas a lista é codificada como "os dígitos de 9587 na base 12" .
Lynn

Entendi obrigado. Queria que você adicionasse uma explicação para que as pessoas que verificam sua resposta possam entender como ela funciona na linguagem escrita.
Vasu Adari

10

gs2, 12 bytes

V@¶4☻s%☺♀i50

Tradução da minha resposta CJam. Codificado no CP437 como de costume. Experimente online !


O link vai para o código que produz 2spooky4me e, se eu recortar e colar o código acima, recebo o ano errado: imgur.com/VAkXT0k (por "ano errado", quero dizer que recebo um ano antes do ano pretendido)
question_asker

Eu tinha esquecido um byte. Tente agora.
Lynn

Também editei o link.
Lynn

Legal, ele funciona agora
question_asker

8

JavaScript (ES6), 50 49 20 bytes (sem bônus)

a=>a+[5,6,6,11][a%4]

O algoritmo do @martin mostra-se muito menor, então fui com ele.

Eu escolhi uma abordagem matemática porque o JavaScript tende a ser detalhado. O código é curto o suficiente para que os bônus o tornem mais longo.

Aqui está minha resposta anterior (49 bytes) e minha resposta original (50 bytes):

F=(a,b=a)=>((a+--a/4|0)-(b++/4+b|0))%7?F(++a,b):b

F=(a,b=a)=>(f=c=>(c--+c/4|0)%7)(a)-f(++b)?F(a,b):b

Eles trabalham tomando o ano e calculando um número (0-6) para representar o "dia do ano inicial". Como o período para esse desafio está dentro do intervalo de anos que seguem regras simples para o ano bissexto (sem pular em 2000), é bastante simples calcular. Depois, basta comparar para encontrar anos que começam com o mesmo valor. A recursão provou ser a maneira mais concisa de fazer isso.


7

Pitão, 14 12 11 bytes

+QC@"♣♠♠♂"Q

Os quatro bytes na string devem ser 05 06 06 0B.

EDIT: Obrigado, FryAmTheEggman!

EDIT: Obrigado, Dennis!


6

JavaScript (ES6), 104 bytes - bônus de 50% = 52

y=>eval('for(a=0;a!=(b=(new Date(""+y++)+"").slice(0,3));a=a||b)`Advance Happy New Year, ${y} (`')+b+")"

Explicação

y=>
  eval(`                  // eval enables for loop without {} or return
    for(
      a=0;                // a = first day of input year
      a!=                 // check if the day of the current year is equal to the first
        (b=(new Date(     // b = day of current year
          ""+y++)+"")     // cast everything as strings!
            .slice(0,3)); // the first 3 letters of the date string are the day name
      a=a||b              // set a to the day on the first iteration
    )

      // return the string
      \`Advance Happy New Year, \${y} (\`
  `)+b+")"

Teste


6

Código da máquina Z80, 12 bytes

Um procedimento Z80 para ser armazenado em 0000h, chamado com a entrada in HLe todos os outros registradores são limpos:

.org 0000h
              ; Bytes   ; Explanation
  ;---------------------------------------------------------------
  DEC B       ; 05      ; 
  LD B, 6     ; 06 06   ;   
  DEC BC      ; 0B      ;
  LD A, 3     ; 3E 03   ;   A = 3
  AND L       ; A5      ;   A = input & 3
  LD E, A     ; 5F      ;   A = input & 3     DE = input & 3
  LD A, (DE)  ; 1A      ;   A = [input & 3]   DE = input & 3
  LD E, A     ; 5F      ;   A = [input & 3]   DE = [input & 3]
  ADD HL, DE  ; 19      ;   HL = input + offset
  RET         ; C9      ;

As três primeiras instruções são "NOPs", mas são indexadas como dados posteriormente no código. Ao retornar, a saída está em HL.


Sim, eu adicionei ao post.
Lynn

Não parece certo para os anos 2097 e 2098, que precisam de acréscimos de 7 e 12, respectivamente.
Toby Speight

11
O OP diz que o ano de entrada é garantido entre 1970 e 1990.
Lynn

6
Eu realmente não gosto de perguntas que foram alteradas depois que eu respondi!
Toby Speight

2
Você tem permissão para especificar que a entrada está dentro DEe, portanto, você pode usar LD A, 3; AND E; LD L, A; LD L, (HL);?
Neil

5

Python 3, 140 100 102 84,5 154 * 0,5 = 77 bytes

Provavelmente eu poderia escrever uma solução melhor com o algoritmo de Sakamoto, mas isso servirá por enquanto

Eu tinha razão. Aqui está uma implementação usando o algoritmo de Sakamoto.

def s(y):
 d=lambda j:(j+j//4)%7
 for i in range(y,y+15):
  if d(i)==d(y-1):return"Advance Happy New Year, %d (%s)"%(-~i,"SMTWTFSuouehranneduit"[d(i)::7])

Explicação:

def day_of_the_week(year):
    return (year + year//4 - 1 + 0 + 1) % 7
    # The month code for January is 0, and you add 1 from January *1*.
    # The -1 is to correct for starting on Saturday 
    # and so that it cancels out the 1 from January 1.

def new_years(this_year):
# But in Sakamoto's algorithm, if the month is January or February, we must subtract 1.
    weekdays = "SunMonTueWedThuFriSat"
    for item in range(this_year, this_year + 15):
        if day_of_the_week(this_year - 1) == day_of_the_week(item):
            day = weekdays[day_of_the_week(item)*3 : day_of_the_week(item)*3+3]
            return "Advance Happy New Year, %d (%s)"%(item + 1, day)
        # So we subtract from every year we check, including this_year
        # And add 1 back in at the end
        # And print the greeting, the year, and the corresponding day of the week

Eu atualizei a pergunta. Você não precisa verificar por anos do século.
Vasu Adari

11
Que tal w="SMTWTFSuouehranneduit"e depois imprimir w[d(i)::7]?
Lynn

4

Sério, 35 17 bytes

[5,6,6,11] truque salva o dia.

4,;)%[5,6,6,11]E+

Experimente online

Explicação:

4,;)%[5,6,6,11]E+
4,;)%              push input, input % 4
     [5,6,6,11]E   push (input % 4)th element of [5,6,6,11]
                +  add to the input

Versão antiga:

,;;D`45/*≈7@%`;╝ƒ╗35*r+`╛ƒ╜=`M1@íu+

Experimente online

Explicação:

,;;D`45/*≈7@%`;╝ƒ╗35*r+`╛ƒ╜=`M1@íu+
,;;                                  push 3 copies of the input (n)
   D                                 decrement the top copy of n
    `45/*≈7@%`;╝                     push Sakamoto's algorithm as a function and save a copy in register 1
                ƒ╗                   call Sakamoto's algorithm function and save result in register 0
                  35*r+              push [n, n+1, ..., n+14]
                       `    `M       map the function:
                        ╛ƒ╜=           push Sakamoto's algorithm, call, push 1 if equal to value in register 0 else 0
                              1@í    get the index of the first 1
                                 u+  increment and add n

Algoritmo de Sakamoto:

45/*≈7@%
45/*      multiply by 5/4
    ≈     floor
     7@%  mod 7

4

C, 31 bytes

Após a edição da pergunta que restringe o intervalo de entrada a 1970-2090, isso se torna bastante trivial:

f(x){return"\5\6\6\13"[x%4]+x;}

Sem os anos do século não bissexto, há uma sequência simples de 5,6,6,11 intervalos para a primeira repetição do mesmo dia.

Solução completa para o problema original (não restrito a 2090), 90 bytes:

f(x){return(x-1)%100>89&&(x+9)/100%4?"\6\14\5\6\6\6\6\7\14\6"[x%10]+x:"\5\6\6\13"[x%4]+x;}

Programa de teste:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    while (*++argv)
        printf("Advance Happy New Year, %d\n", f(atoi(*argv)));
    return !argc;
}

Execução de teste:

$ ./66656 2001 2047 2014 1970 1971 1977 2006
Advance Happy New Year, 2007
Advance Happy New Year, 2058
Advance Happy New Year, 2020
Advance Happy New Year, 1976
Advance Happy New Year, 1982
Advance Happy New Year, 1983
Advance Happy New Year, 2012

4

R, 143 136 * 0,5 = 68 bytes

G=function(y)strftime(paste(y,1,1,sep='-'),'%a')
d=seq(y<-scan(),y+14);sprintf("Advance Happy New Year, %i (%s)",d[G(d)==(w=G(y))][2],w)

Usar %A para o nome do dia inteiro em vez de `% a, depende do estado desejado.

R, 120 * 0,7 = 84 bytes

G=function(y)as.POSIXlt(paste(y,1),,"%Y %j")$wday
d=seq(y<-scan(),y+14);cat("Advance Happy New Year,",d[G(d)==G(y)][2])

R, 90 bytes

G=function(y)as.POSIXlt(paste(y,1),,"%Y %j")$wday
d=seq(y<-scan(),y+14);d[G(d)==G(y)][2]

Todas as respostas acima são trabalhos derivados baseados na resposta @plannapus. Usando o ;separador para evitar a necessidade sourcedo arquivo ou executá-lo como script na linha de comando.


11
+1 Eu esqueci completamente weekdays, legal.
plannapus

@ plannapus Obrigado :) (contei as novas linhas, perguntei ao sistema de arquivos de fato, pois estou no Windows com 2 bytes, mas não tenho uma nova linha no final que um arquivo POSIX deve ter, por isso é justo mantê-lo assim na verdade)
Tensibai

3

R, 145 bytes -50% -> 72,5

y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%a");x=y+1;while(F(x)!=F(y))x=x+1;sprintf("Advance Happy New Year, %i (%s)",x,F(x))

Exemplos:

> y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%a");x=y+1;while(F(x)!=F(y))x=x+1;sprintf("Advance Happy New Year, %i (%s)",x,F(x))
1: 2006
2: 
Read 1 item
[1] "Advance Happy New Year, 2012 (Sun)"
> y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%a");x=y+1;while(F(x)!=F(y))x=x+1;sprintf("Advance Happy New Year, %i (%s)",x,F(x))
1: 1977
2: 
Read 1 item
[1] "Advance Happy New Year, 1983 (Sat)"
> y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%a");x=y+1;while(F(x)!=F(y))x=x+1;sprintf("Advance Happy New Year, %i (%s)",x,F(x))
1: 2014
2: 
Read 1 item
[1] "Advance Happy New Year, 2020 (Wed)"

R, 97 bytes (sem bônus)

y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%w");x=y+1;while(F(x)!=F(y))x=x+1;x

Recuado, com novas linhas:

y = scan() #Takes input from stdin
F = function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%w") #Year to Weekday
x = y+1
while(F(x) != F(y)) x = x+1
x

Casos de teste:

> y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%w");x=y+1;while(F(x)!=F(y))x=x+1;x
1: 1977
2: 
Read 1 item
[1] 1983
> y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%w");x=y+1;while(F(x)!=F(y))x=x+1;x
1: 2006
2: 
Read 1 item
[1] 2012
> y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%w");x=y+1;while(F(x)!=F(y))x=x+1;x
1: 2016
2: 
Read 1 item
[1] 2021

Eu não entendo este desejo de ficar em uma linha feia, um retorno de carro não é mais caro do que um ;...
Tensibai

você pode salvar um caractere removendo o primeiro y=scan;e usando x=y<-scan()+1Acho
Tensibai

e você pode economizar mais sete usando as.POSIXlt(paste(y,1),,"%Y %j")$wdaycomo seu corpo funcional
Tensibai

@Tensibai, se você não colocá-lo em uma única linha e colá-lo diretamente no console, scanirá ler na segunda linha como entrada. x=y<-scan()+1com 2014 como stdin, você fornecerá x = 2015 ey = 2015 (ou seja, a atribuição é y <- scan()+1) e, se você tentar fazer x=1+y<-scan()isso, receberá um erro ( Error in 1 + y <- scan() : target of assignment expands to non-language object) porque está tentando atribuir scan()a 1+y.
plannapus

@Tensibai Quanto ao seu último conselho, os resultados ...$wdayé o número da semana: mas aqui eu preciso o nome da semana para que eu possa imprimirAdvance Happy New Year, 2012 (Sun)
plannapus

3

VBA, 130 * 0,50 = 65 bytes

Sub k(y)
i=1
Do While Weekday(y+i)<>Weekday(y)
i=i+1
Loop
MsgBox "Advance Happy New Year," &y+i &WeekdayName(Weekday(y+i))
End Sub

O VBA facilita a busca por dias da semana ... Se ao menos não fosse tão detalhado.


3

PHP, 120 139 bytes - 50% = 60 bytes

Uma abordagem funcional:

$s=strtotime;for($d=date(D,$s(($y=$argv[1]).$_="-1-1"));$d!=date(D,$s(++$y.$_)););echo"Advance Happy New Year, $y ($d)";

Toma uma entrada da linha de comando, como:

$ php ahny.php 2001

O caminho OOP parece ser mais longo, como sempre (143 bytes):

$s=strtotime;for($d=date(D,$s($x=($y=$argv[1])."-1-1"));$d!=date(D,$s(++$y."-1-1")););echo"Advance Happy New Year, $y ($d)";

Edições

  • Salva 18 bytes . Em vez de adicionar um ano usando o modificador PHP +1year, agora simplesmente incremento o ano indicado.
  • Economizou 1 byte armazenando -1-1em uma variável.

3

C, pontuação 53 52 (104 bytes)

f(x){x+="0116"[x%4];printf("Advance Happy New Year, %d (%.3s)",x-43,"MonTueWedThuFriSatSun"+x*5/4%7*3);}

Ideia emprestada de Toby Speight ; adicionada a exibição de bônus do dia da semana.

Encurtou a corda alterando os códigos de caracteres para um intervalo mais confortável. Tinha que escolher a quantidade de deslocamento correta (por exemplo, 43) para fazer o código de cálculo de dias úteis curto x*5/4%7.


Acho que o código do seu personagem restringe isso a codificações compatíveis com ASCII?
Toby Speight

Sim. Os códigos devem ser maiores que 31, portanto, o número mínimo a ser adicionado aos códigos seria 27, fornecendo a sequência " !!&".
anatolyg

2

Mathematica, 145 * 50% = 74 73,5 72,5 bytes

d=DateValue;StringForm["Advance Happy New Year, `` (``)",NestWhile[#+1&,(a=#)+1,#!=#2&@@DateObject@{{a},{#}}~d~"DayName"&],{a}~d~"DayNameShort"]&

Usa funções de data padrão.


2

Pitão, 23 bytes

L%+/b4b7.VQIqyby-Q1+1bB

Não se qualifica para nenhum dos bônus.

Experimente aqui .

Semelhante à resposta python pura.

                        - Q = eval(input()) (autoassigned)
L                       - y = lambda b:
   /b4                  - b floordiv 4
  +   b                 - + b
 %     7                - mod 7


        .VQ             - for b in range(Q, infinate):
           Iqyby-Q1     - if y(b) == y(Q-1):
                   +1b  - print b+1
                      B - break

2

Java, (1-.2) * 323 (1-.5) * 350 348 339 = 258,4 175 174 169,5 bytes

import java.text.*;class D{public static void main(String[]a){long y=new Long(a[0]);int i=0;for(;!s(y).equals(s(y+(++i))););System.out.printf("Advance Happy New Year, %d (%s)",y+i,s(y+i));}static String s(long y){try{return new SimpleDateFormat("E").format(new SimpleDateFormat("d/M/yyyy").parse("1/1/"+y));}catch(Exception e){}return"";}}

Ugh.

Ungolfed:

import java.text.*;
class D{
    public static void main(String[]a){
        long y=new Long(a[0]);
        int i=0;
        for(;!s(y).equals(s(y+(++i))););
        System.out.printf("Advance Happy New Year, %i (%s)",y+i,s(y+i));
    }
    static String s(long y){
        try{
            return new SimpleDateFormat("E").format(new SimpleDateFormat("d/M/yyyy").parse("1/1/"+y));
        }catch(Exception e){}
        return"";
    }
}

Experimente online!

Obrigado a @Kenney por apontar que eu poderia diminuir com new Longe printf! : D


long y=new Long(a[0])salva 6 (12) bytes e o uso printfsalva outros 3 (6).
22615 Kenney

2

Coreutils GNU, 52 51 49 bytes

(Programa de 98 bytes - bônus de 50%)

seq -f$1-1-1\ %gyear 28|date -f- +'Advance Happy New Year, %Y (%a)'|sed /`date -d$1-1-1 +%a`/!d\;q

A entrada é do argumento da linha de comando e a saída é para stdout.

Explicação

# generate 28 input years from $1 + 1 onwards (28 is always enough)
seq -f '$1-1-1 %g year' 28
|
# convert all of these as potential outputs
date -f- +'Advance Happy New Year, %Y (%a)'
|
 # Select the first one where the dayname matches that of input year
sed "/`date -d$1-1-1 +%a`/!d;q"

Execução de teste:

Todas as configurações de localidade podem ser Cou POSIX.

$ for i in 2001 2047 2014 1970 1971 1977 2006; do ./66656.sh $i; done
Advance Happy New Year, 2007 (Mon)
Advance Happy New Year, 2058 (Tue)
Advance Happy New Year, 2020 (Wed)
Advance Happy New Year, 1976 (Thu)
Advance Happy New Year, 1982 (Fri)
Advance Happy New Year, 1983 (Sat)
Advance Happy New Year, 2012 (Sun)

Limitação: isso funciona apenas até o ano 2147485519 (embora a pergunta agora tenha sido alterada para permitir um limite mais baixo).


2

MATL , 28 bytes

i0:14+t1tI$YO8H$XO!st1)=f2))

Exemplo

>> matl i0:14+t1tI$YO8H$XO!st1)=f2))
> 1970
1976

Código explicado

i           % input year
0:14+       % vector with that year and the next 14
t1tI$YO     % first day of each year
8H$XO       % transform into three letters specifying weekday
!s          % sum those three letters to reduce to unique numbers
t1)         % get first of those numbers (corresponding to input year)
=f2)        % find index of second matching
)           % index with that to obtain output year

2

Perl 6 ,  70   23 bytes

{($^a+1...{[==] ($a,$_).map: {Date.new(:year($_)).day-of-week}})[*-1]} # 70 bytes

{($_ X+5,6,6,11)[$_%4]} # 23 bytes

uso:

for «2001 2047 2014 1970 1971 1977 2006 2010» {
  printf "%d => %d\n", $_, {($_ X+5,6,6,11)[$_%4]}( $_ )
}
2001 => 2007
2047 => 2058
2014 => 2020
1970 => 1976
1971 => 1982
1977 => 1983
2006 => 2012
2010 => 2016


2

Japonês, 12 bytes

U+"♣♠♠♂"cU%4

Como na resposta Pyth, os quatro bytes na string devem ser 05 06 06 0B. Experimente online!

U+"♣♠♠♂"cU%4  // Implicit: U = input integer
  "♣♠♠♂"      // Take this string.
        cU%4  // Take the char code at U%4.
U+            // Add U.
              // Implicit: output last expression

2
Obrigado por este presente de Natal de uma recompensa! Mas alguém pode me dizer como eu ganhei?
ETHproductions

Eu olhei através da história. Aparentemente, o OP tentou recompensar uma resposta, mas esqueceu de conceder a recompensa, então a Comunidade optou por passar metade da reputação para essa resposta (acho que baseia sua escolha em votações recentes).

2

Gelatina , 14 bytes

%4=0,3×-,5S++6

Experimente online!

Até hoje, Jelly não tinha indexação de matriz, portanto, o que foi dito acima terá que ser feito. Desde a confirmação mais recente, a indexação de matriz foi implementada como , fornecendo a seguinte solução ( 10 bytes ).

ị6,6,11,5+

Experimente online!


11
Eu acho que Jelly pode poupar 7 caracteres para 10 ~ 16 constantes.
lirtosiast


1

C # (6.0) .Net Framework 4.6 173 bytes - 30% = 121.1 bytes

void n(int y)=>Console.Write($"Advance Happy New Year, {Enumerable.Range(1,15).Select(i=>new DateTime(y+i,1,1)).First(x=>x.DayOfWeek==new DateTime(y,1,1).DayOfWeek).Year}");


1

Python, 23 bytes

lambda a:a+5+(a%4)**3%7

Uma porta da minha resposta JavaScript.


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.