Avance Feliz Año Nuevo, 2016!


40

Su entrada será un número entero entre 1970 y 2090 (inclusive), que representa un año. Su programa debería generar el próximo año en el que el Día de Año Nuevo cae en el mismo día de la semana que el año de entrada.

Casos de prueba:

A continuación se muestran las entradas y salidas de muestra.

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

20% de bonificación: salida el día de la semana del día de año nuevo

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

30% de bonificación: salidaAdvance Happy New Year, <year>

2010 => Advance Happy New Year, 2016

50% de bonificación: haz las dos bonificaciones anteriores

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

Escriba un programa que lea la entrada de STDIN o acepte argumentos de línea de comandos, o una función que tome un argumento.

Nota: Agregue un enlace para probar su código si es posible.

Tabla de clasificación:


66
Siento que cada desafío de fechas requiere el cálculo de los años bisiestos como un subproblema, y ​​se está volviendo obsoleto.
xnor

Relacionado: esta pregunta .
Addison Crump

@xnor Si ese no fuera el caso, habría sido solo un +7. Es decir, "demasiado amplio"
Erik the Outgolfer

@EriktheGolfer No. Cuando escribí ese comentario, mi respuesta fue la aceptada.
Dennis

Respuestas:


1

Jalea, 9 bytes

%4*3%7+5+

Esta es una cadena monádica que toma un argumento de línea de comando entero como entrada. Utiliza mi (x+5+(x%4)**3%7)algoritmo.

Probarlo aquí . Aunque esa es la versión actual de Jelly, también funciona en esta versión , que es anterior al desafío. (¡Gracias @ Dennis!)


¡Esto es increíble! Puedo confirmar que funciona con esta revisión del intérprete Jelly, que es anterior al desafío.
Dennis

31

Mathematica, 45 37 27 24 bytes

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

Mejoras gracias a @ MartinBüttner (10 bytes) y @ChipHurst (otros 3 bytes).


77
Oh wow. Nadie parece haber notado este patrón, pero funciona.
Lynn

44
Aquí hay una versión un poco más corta:#+5[6,6,11][[#~Mod~4]]&
Chip Hurst

@ChipHurst muy inteligente con 5[6, 6, 11][[0]]:)
martin

18

CJam, 21 12 11 bytes

{_9587Cb=+}

@martin encontró un método muy simple!

Probarlo aquí .

EDITAR: ¡Gracias, Dennis!


1
@Mauris ¿Podría agregar una explicación?
Vasu Adari

@Vasu: este código es una función anónima que implementa el mismo 5 6 6 11truco utilizado en otras respuestas, pero la lista está codificada como "los dígitos de 9587 en la base 12" .
Lynn

Gracias. Quería que agregaras una explicación para que las personas que verifican tu respuesta puedan entender cómo funciona el lenguaje wrt.
Vasu Adari

10

gs2, 12 bytes

V@¶4☻s%☺♀i50

Traducción de mi respuesta CJam. Codificado en CP437 como de costumbre. Pruébalo en línea !


El enlace va al código que produce 2spooky4me, y si corto y pego el código anterior, obtengo el año incorrecto: imgur.com/VAkXT0k (por "año incorrecto", quiero decir que obtengo un año antes del año previsto)
question_asker

Había olvidado un byte. Probar ahora.
Lynn

También edité el enlace.
Lynn

Genial, funciona ahora
question_asker

8

JavaScript (ES6), 50 49 20 bytes (sin bonificaciones)

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

El algoritmo de @martin demuestra ser mucho más pequeño, así que lo seguí.

Elegí un enfoque matemático porque JavaScript tiende a ser detallado. El código es lo suficientemente corto como para que los bonos solo lo alarguen.

Aquí está mi respuesta anterior (49 bytes) y mi respuesta 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

Trabajan tomando el año y calculando un número (0-6) para representar el "día de inicio del año". Debido a que el rango de fechas para este desafío se encuentra dentro del rango de años que siguen reglas simples de año bisiesto (sin saltarse el año 2000), es bastante sencillo de calcular. Entonces es solo cuestión de comparar para encontrar años que comiencen con el mismo valor. La recursión demostró ser la forma más concisa de hacer esto.


7

Pyth, 14 12 11 bytes

+QC@"♣♠♠♂"Q

Los cuatro bytes en la cadena deben ser 05 06 06 0B.

EDITAR: ¡Gracias, FryAmTheEggman!

EDITAR: ¡Gracias, Dennis!


6

JavaScript (ES6), 104 bytes - 50% de bonificación = 52

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

Explicación

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+")"

Prueba


6

Código máquina Z80, 12 bytes.

Un procedimiento Z80 para ser almacenado en 0000h, llamado con la entrada HL, y todos los demás registros borrados:

.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      ;

Las primeras tres instrucciones son "NOP", pero se indexan como datos más adelante en el código. Al regresar, la salida está adentro HL.


Sí, lo he agregado a la publicación.
Lynn

No se ve bien en los años 2097 y 2098, que necesitan adiciones de 7 y 12, respectivamente.
Toby Speight

1
El OP dice que el año de entrada está garantizado en el rango 1970-2090.
Lynn

66
¡Realmente no me gustan las preguntas que cambian después de haber respondido!
Toby Speight

2
¿Se le permite especificar que la entrada está dentro DEy, por lo tanto, puede usarla 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

Probablemente podría escribir una mejor solución con el algoritmo de Sakamoto, pero esto funcionará por ahora

Yo tenía razón. Aquí hay una implementación usando el 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])

Explicación:

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

He actualizado la pregunta. No necesita verificar durante los años del siglo.
Vasu Adari

1
¿Qué tal w="SMTWTFSuouehranneduit"y luego imprimir w[d(i)::7]?
Lynn

4

En serio, 35 17 bytes

[5,6,6,11] El truco salva el día.

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

Pruébalo en línea

Explicación:

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

Versión antigua:

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

Pruébalo en línea

Explicación:

,;;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

Después de editar la pregunta que restringe el rango de entrada a 1970-2090, esto se vuelve bastante trivial:

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

Sin los años del siglo no bisiesto, hay una secuencia simple de intervalos de 5,6,6,11 para la primera repetición del mismo día.

Solución completa al problema original (no limitado 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 prueba:

#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;
}

Prueba de funcionamiento:

$ ./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, 143136 * 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)

Utilizar %A para el nombre de día completo en lugar de `% a, depende del estado deseado.

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 las respuestas anteriores son trabajos derivados basados ​​en la respuesta @plannapus. Usar el ;separador para evitar la necesidad sourcedel archivo o ejecutarlo como script en la línea de comando.


1
+1 Me olvidé por completo weekdays, bien.
plannapus

@plannapus Gracias :) (conté las nuevas líneas, de hecho le pregunté al sistema de archivos, ya que estoy bajo Windows, son 2 bytes pero no tengo una nueva línea al final que debería tener un archivo POSIX, por lo que es justo mantenerlo así en realidad)
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))

Ejemplos:

> 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 (sin bonificación)

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

Sangrado, con nuevas líneas:

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 prueba:

> 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

No entiendo este deseo de subir a una línea fea, un retorno de carro no es más costoso que un ;...
Tensibai

puedes guardar 1 char quitando el primero y=scan;y usando x=y<-scan()+1creo
Tensibai

y puede ahorrar siete más si lo usa as.POSIXlt(paste(y,1),,"%Y %j")$wdaycomo su cuerpo de función
Tensibai

@Tensibai, si no lo coloca en una sola línea y lo pega directamente en la consola, scanse leerá en la segunda línea como entrada. x=y<-scan()+1con 2014 como entrada estándar le dará x = 2,015 ey = 2015 (es decir, la asignación es y <- scan()+1) y si se intenta hacer x=1+y<-scan()que le dará un error ( Error in 1 + y <- scan() : target of assignment expands to non-language object) porque está tratando de asignar scan()a 1+y.
plannapus

@Tensibai En cuanto a su último consejo, el resultado ...$wdayes el número del día de la semana: pero aquí necesito el nombre del día de la semana para poder 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

VBA hace que encontrar los días de la semana sea tan fácil ... Si no fuera tan detallado.


3

PHP, 120139 bytes - 50% = 60 bytes

Un enfoque 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 una entrada de la línea de comando, como:

$ php ahny.php 2001

La forma de OOP parece ser más larga, como siempre (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)";

Ediciones

  • Guardado 18 bytes . En lugar de agregar un año usando el modificador de PHP +1year, ahora simplemente incremento el año dado.
  • Se guardó 1 byte almacenando -1-1en una variable.

3

C, puntaje 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);}

Idea tomada de Toby Speight ; Se agregó la pantalla de bonificación del día de la semana.

Acortó la cadena cambiando los códigos de caracteres a un rango más cómodo. Tuve que elegir la cantidad de desplazamiento correcta (por ejemplo, 43) para que el código de cálculo de día laborable corto x*5/4%7funcionara.


Supongo que el código de tu personaje restringe esto a codificaciones compatibles con ASCII
Toby Speight

Sí. Los códigos deben ser mayores que 31, por lo que el número mínimo para agregar a los códigos sería 27, dando la cadena " !!&".
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"]&

Utiliza funciones de fecha estándar.


2

Pyth, 23 bytes

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

No califica para ninguno de los bonos.

Pruébalo aquí .

Similar a la respuesta pura de Python.

                        - 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

Sin golf:

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"";
    }
}

Pruébalo en línea!

¡Gracias a @Kenney por señalar que podría acortar con new Longy printf! :RE


long y=new Long(a[0])ahorra 6 (12) bytes, y el uso printfguarda otros 3 (6).
Kenney

2

GNU coreutils, 52 51 49 bytes

(Programa de 98 bytes - 50% de bonificación)

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

La entrada es del argumento de la línea de comandos y la salida es stdout.

Explicación

# 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"

Prueba de funcionamiento:

Todas las configuraciones regionales pueden ser Co 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)

Limitación: esto solo funciona hasta el año 2147485519 (aunque la pregunta ahora se ha cambiado para permitir un límite inferior).


2

MATL , 28 bytes

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

Ejemplo

>> 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

Japt, 12 bytes

U+"♣♠♠♂"cU%4

Al igual que con la respuesta de Pyth, los cuatro bytes en la cadena deberían ser 05 06 06 0B. Pruébalo en línea!

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
Gracias por este regalo de Navidad de una recompensa! ¿Pero alguien puede decirme cómo lo gané?
ETHproductions

Miré a través de la historia. Aparentemente, el OP intentó recompensar una respuesta, pero se olvidó de otorgar la recompensa, por lo que Community eligió pasarle la mitad de la reputación a esta respuesta (creo que basa su elección en votos recientes).

2

Jalea , 14 bytes

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

Pruébalo en línea!

Hasta hoy, Jelly no tenía indexación de matriz, por lo que lo anterior tendrá que hacer. Desde la última confirmación, la indexación de matriz se ha implementado como , dando la siguiente solución ( 10 bytes ).

ị6,6,11,5+

Pruébalo en línea!


1
Creo que Jelly puede ahorrar 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

Un puerto de mi respuesta de JavaScript.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.