Премьер среды


22

Премьер среды

Ваша задача - подсчитать количество сред, которые выпадают на основной день месяца в определенном году. Например, 7-13-16это премьер среда. Для согласованности используйте григорианский календарь на все даты.

вход

Вход в вашу программу / функцию будет год (например 2016) и является гибким. Год будет целым числом между 1912 и 2233 включительно.

Выход

Выход также является гибким и должен быть числом простых сред (например 18).

счет

Это поэтому выигрывает самый короткий код в байтах!

Тестовые случаи

вход -> выход
--------------------
1912 -> 19
1914 -> 16
1984 -> 17
1996 -> 19
2063 -> 19
2150 -> 16
2199 - > 18
2233 -> 18

Ответы:


7

MATL , 38 36 34 байта

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

Попробуйте онлайн! Или проверьте все тестовые случаи (занимает несколько секунд).

объяснение

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

Я убежден, что MATL не может быть побежден на вызовах на основе даты. Мы должны создать DATL, который будет дополнительно оптимизирован для решения задач на основе дат.
Сувер

@ Сувер Ха-ха, хорошее имя
Луис Мендо

20

Python 2, 95 93 68 67 байт

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

Спасибо @Josay за игру в гольф на 1 байт!

Проверьте это на Ideone .


3
Вы можете сохранить 1 символ 0x10ea2c8dbb06c5619вместо 19501370182350951961.
SylvainD

Я понимаю идею, big_constant//5**long_expressionно как на Земле вы пришли с этой константой и этим выражением? Это безумие: D
Sherlock9

2
Константа представляет собой простую справочную таблицу, в которой используются цифры 5 из базы, но она преобразуется в базу 10, так что цифры извлекаются численно, а не с использованием строкового индекса. Выражение выглядит как вечный календарь для меня. (Проблема была бы слишком простой, если бы она была ограничена годами с 1901 по 2099 гг., Поскольку ответы повторяются каждые 28 лет в пределах этого интервала, так что это был бы всего лишь случай выбора мод года 28 и поиска его в таблице. )
Нил

13

Brain-Flak , 6588 , 2310 , 2308 , 2290 байт

Перво-наперво, я не написал почти 100% этой программы, о чем, вероятно, свидетельствует огромный размер программы. Большая часть этого кода была написана моим собственным алгоритмом игры в гольф Brain-Flak . Наряду с дополнительным скриптом Python я написал, чтобы подсказать в правильном направлении.

Попробуйте онлайн!

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

Хотя эта программа довольно длинна для кода гольфа, она действительно коротка для Brain-Flak. В настоящее время мировой рекорд по целочисленному разделению составляет более 1000 байтов.

объяснение

Алгоритм довольно прост. Поскольку доступно ограниченное количество лет (321), он просто помещает ответы в обратном порядке под входными данными и использует алгоритм поиска, чтобы найти правильный ответ. Хотя жесткое кодирование всех 321 возможностей может показаться довольно неэффективным с такой сложной задачей, как эта, и с таким эзотерическим языком, как мозговая атака, вполне может оказаться лучшим решением. (Планирую узнать в ближайшие недели).

Так как большинство из 321 чисел составляют в среднем около 18 и они очень мало отличаются от года к году, вместо того, чтобы нажимать все числа индивидуально, я обычно нажимаю первый год (2233), а затем просто дублирую и немного меняю значение для каждого года после. Таким образом, вместо того, чтобы платить за толчок ~ 18 за все 321 год, я плачу только за толчок ~ 2 за каждый год.

После того, как все ответы были выдвинуты, он вычитает 1912 из входных данных ({}[(((((((((()()()()())){}{}){}){}){}){}[()]){}){}){}])(Это может быть неоптимальным, я переписал оптимизатор, чтобы пропустить определенные значения, которые, по моему мнению, не были бы оптимальными, поскольку жесткое кодирование чисел - это суперэкспоненциальный процесс, и выполнение его до завершения может иметь заняло несколько дней).

Затем он вычитает единицу из первого элемента и выталкивает второй элемент, пока результат не достигнет нуля {({}[()]<{}>)}.

Он выскакивает ноль, {}и все элементы ниже верхнего элемента ({}<{{}}>).


Каков общий подход к играм в гольф?
Нил

Простая идея состоит в том, что если у вас есть число с коэффициентами n и m, вы нажимаете n m-1 раз, а затем выдвигаете m-1 раз. Первоначальный толчок оценивается как n, и каждый всплеск оценивается как дополнительный n, делая для (1 + m-1) (n) то же самое, что и mn. Это делается рекурсивно, потому что для того, чтобы подтолкнуть n, мы также должны сыграть в гольф n. Поскольку этот метод не работает для некоторых чисел, особенно простых чисел, мы также посмотрим, есть ли рядом более эффективное число, и если да, то мы выражаем это как сумму этого числа и разницы.
Пшеница Волшебник

Понятно ... поэтому, учитывая два числа nи mкоторые имеют длину kи l, я полагаю, n+mбудет иметь длину k+l? Как насчет n*m?
Нил

n*mбудет k+4m-4или l+4n-4. Это потому, что умножение жестко закодировано. Мы сначала толкаем n m-1времена. Для этого нам нужны kсимволы для выражения nи 2m-2символы для выражения толчков (каждый толчок - 2 символа). Затем мы добавляем m-1время, что обходится нам дополнительно 2m-2(стоимость 2 символа тоже). Это составляет до k+4m-4. мы также можем умножить m*n(коммутативное свойство), чтобы получить l+4n-4. Результат будет короче из двух.
Пшеничный Волшебник

1
Ну, если это правда, то +1стоит 2, *2стоит 4, *3стоит 8, *4стоит 12, что дороже *2*2, поэтому не стоит (из чисел ниже 1000 я нашел только 10, которые не использовали *2: 1, 2, 3 4, 5, 9, 15, 27, 45, 135). Для 1912 года лучшее, что я мог сделать, было ((((((1+1+1)*2+1)*2*2+1)*2+1)*2+1)*2+1)*2*2*2с длиной 52.
Нил

7

Баш + коммунальные услуги, 39

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

Принимает год ввода в качестве параметра командной строки. Обычно выводит подобные сообщения в STDERR - я думаю, что это законно в соответствии с этим мета-ответом :

factor: We is not a valid positive integer

Если вы хотите явно подавить вывод STDERR, вы можете сделать это вместо этого для оценки 43 :

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

Обратите внимание, что это предполагает английский или C / POSIX языковой стандарт. Это не очень хорошо работает там gd_GB.utf8, где сокращаются названия всех дней Di.
Тоби Спейт

6

Октава, 86 байт

Это не быстро, ни в коем случае. Но на самом деле это не цель код-гольфа, не так ли?

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

Octave может отслеживать даты по «номеру даты» - количеству прошедших дней, когда 1, 0 января - день 1. По этому показателю 3 января 1912 года (первая среда в нашем наборе) - день 698 346. Начните с этого и повторяйте каждый седьмой день (все среды) до конца 2233 года, и добавьте 1, если год является целевым годом, а день месяца является основным.


5

Python 2,7, 166 , 165 , 150 байт

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

Здесь, безусловно, есть место для улучшения. Я довольно новичок в гольф в питоне. Это использует datetimeмодуль. Он проходит по всем дням года, добавляя один к аккумулятору, если он соответствует критерию. Затем он печатает результат. Большая часть тяжелой работы находится в модуле, поэтому код может быть довольно тонким.

Один байт сохранен благодаря Morgan Thrapp и 15 байтов сохранены Pietu1998 .


1
Вы можете сохранить один байт, переключившись n%x==0на n%x<1.
Морган Трепп

2
Не -1является необходимым, поскольку rangeконечный индекс является эксклюзивным. Кроме того, вы можете преобразовать в filterгенератор. [0for x in range(2,n)if n%x<1]
PurkkaKoodari

Вы можете использовать any(...)или all(...)вместо not filter(...).
Кеннитм

1
Комбинируя цепные сравнения, allвы можете сохранить целую кучу. c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n))
PurkkaKoodari

3

J, 44 байта

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

Я только что обнаружил, что у J есть встроенные функции для манипулирования датами.

использование

Дополнительные команды используются для форматирования нескольких входов / выходов.

   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

объяснение

+/@(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

1

PowerShell v3 +, 99 95 байт

Метод грубой силы -

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

Принимает входные данные $y, циклы от 1до 12, временно сохраняет месяц в $m, а затем циклы по каждому простому числу от 2до 31. Для каждого из них мы строим Get-Dateопределенный день, а затем выбираем только те, которые имеют DayOfWeek -eqзначение 3(т.е. среда). Инкапсулирует это все в паренсе, чтобы сформулировать массив, и берет .Countего.


Альтернативно, математический подход -

PowerShell v3 +, 105 байт

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)

Получается, что это всего лишь волосы длиннее, чем подход грубой силы, но я включил это здесь, поскольку это может быть полезно для других.

Снова принимает данные $yкак год. На этот раз мы выполняем строго математические операции в первый день года. Сначала мы вычисляем, какой это день недели, и сохраняем его $aдля последующего использования. Это индексирует в первый массив, который возвращает нам число, которое обычно является правильным. Мы должны добавить к этому второй индекс, основанный на том, является ли это потенциальным високосным годом, будь то воскресенье, вторник, среда или четверг, и на основе того, какой это год.

Это основано на следующем наблюдении. Первый столбец - это день недели 1 января, второй - обычный вывод. Если год не является одним из средних чисел, то вместо этого это число в скобках. Последний столбец описывает, как работает индексирование% 5.

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

Примечание. Оба предположения en-usявляются текущими настройками PowerShell для информации о культуре / дате. Форматирование даты и DayOfWeekчисло, возможно, должны быть скорректированы соответственно для других вариантов культуры.



1

JavaScript ES6, 187 182 181 179 байт

179 Поменяны местами в цикле for для цикла 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 Уплотненный троичный

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 Объединены две петли

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}

Я не думаю, что это считается, поскольку вы дали первую начальную среду для конкретного года, в этом примере. Задача ОП гласит, что ему нужен год в качестве единственного параметра ... Пока что большие усилия ...
WallyWest

«Входом для вашей программы / функции будет год», но это не то, на что вы указываете. Я использую первую среду 1912 года в качестве начального числа, потому что она есть или наступает перед любой другой средой в период времени, заданный ФП, но я также мог бы легко использовать любую произвольную среду 1911 года или раньше, чтобы посеять ее. Вход в мою функцию по-прежнему составляет год, и функция по-прежнему рассчитывает число простых сред в любом конкретном году в сроки, предложенные ОП, поэтому я не уверен, как это не соответствует задаче.
Пандакодер

Ах, извинения ... Сначала я не осознавал, что вы используете это как компонент посева ... Отличная идея ... Особенно учитывая, что ваше решение превосходит мое примерно на 30 ...;)
WallyWest

1
Спасибо. Я черпал вдохновение в реализации Brain-Flak от Eamon Olive, в которой, по его объяснению, фактически запрограммированы все ответы.
Пандакодер

1

Пакетный, 248 байт

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

Пояснение: dэто день недели с 0понедельником, который обычно 1 января 1912 года. lЭто флаг того, является ли год високосным годом 1для 1912 года. Затем мы переходим с 1913 года на год ввода, обновляя день неделю и пересчет флага високосного года, как мы идем. Наконец, мы используем флаг високосного года и день недели для индексации того, что фактически является большим оператором переключения для определения nколичества простых сред. Установка nв 20 и уменьшение его с понижением, хотя и дешевле, чем использование логики управления потоком, но в результате получается, что если 1 января не високосного года - четверг или воскресенье, то для других случаев будет 16 простых сред и т. Д. ,


1

JavaScript ES6 206 203 199 197 195 183 182 179

Не самое короткое, но лучшее, что я могу сделать сейчас ... Добро пожаловать в предложения по игре в гольф ...

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

Изменения:

  1. изменение троичного компонента из: 3>=x?3-x:10-xв 6-(x+10)%7, сохранение: 3 изменения местоположения декларации;
  2. объединены x=w.getDay();z=D(w,6-(x+10)%7)с z=D(w,6-(w.getDay()+10)%7)сохранением: 4
  3. переместился Z=0из forцикла в объявление даты и вставил z=D(w,6-(x+10)%7)в forцикл, чтобы привести в порядок, сохранив: 2
  4. сдвинули w=new Date(a,Z=0,1)объявление в forцикл, объединив с существующим wобъявлением, сохранив: 2
  5. переписать функцию простого поиска в функцию простого тестирования, сохранив: 12
  6. изменение +!!на ~~уменьшение и преобразование p(d=1)из NaNв 0, что позволяет функции Prime Test по-прежнему работать, сохраняя: 1
  7. Переместил все дополнительные функции из основной вызывающей функции W, переопределил forцикл - перешел в обратном порядке с 31 декабря, Dateзаписал объект как отдельную переменную, затем переписал forцикл в evalвызов; сохранение 3.

@PandaCoder, я тебя догоняю, приятель!


1

R 149 147 байт

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)])}

Проверьте это на Ideone .


0

Groovy, 126

Groovy не имеет проверки простых чисел, его тоже нужно было построить.

{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]}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.