loading...

Daily Challenge #27 - Unlucky Days

thepracticaldev profile image dev.to staff ・1 min read

Friday 13th or Black Friday is considered as an unlucky day. Calculate how many unlucky days are in the given year.

Can you find the number of Friday 13th in the given year? Good luck!

Input: Year as an integer.

Output: Number of Black Fridays in the year as an integer.

Examples:

unluckyDays(2015) == 3
unluckyDays(1986) == 1

Note: In Ruby years will start from 1593.


This challenge comes from user suic. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge for a future post? Email yo+challenge@dev.to with your suggestions!

Discussion

pic
Editor guide
Collapse
alvaromontoro profile image
Alvaro Montoro

JavaScript

const unluckyDays = year => {
  let unlucky = 0;
  for (x = 0; x < 12; x++) {
    unlucky += new Date(year, x, 13).getDay() === 5 ? 1 : 0;
  }
  return unlucky;
}

Live demo on CodePen

Collapse
wheatup profile image
Hao

Brilliant solution, very simple and effective. Although I think ? 1 : 0 is not necessary :p

Collapse
alvaromontoro profile image
Alvaro Montoro

Yes. It's not really necessary because true is turn into 1, and false to 0. I have a second version using that and a reducer in the demo.

Collapse
willsmart profile image
willsmart

Javascript shorty

matchingDayCount = (year, dayOfMonth=13, dayOfWeek=5) => 
  [...Array(12)].reduce((acc, _, month) =>
    acc + Number(new Date(year, month, dayOfMonth).getDay() == dayOfWeek), 0)

[2015, 1986].map(y => matchingDayCount(y)).join() // >> 3,1
Collapse
hoffmann profile image
Peter Hoffmann

Javascript:

function unluckyDays(year) {
    return [[2, 1, 3, 1, 1, 2, 2], [1, 2, 2, 1, 1, 3, 2]]
    [+(year % 400 === 0 || year % 4 === 0 && year % 100 > 0)]
    [new Date(year, 0, 13).getDay()]
}

You can determine the number of Fridays in a given year as the number of days between the 13th of one and the next month is fixed. All you need to know is the day of January 13th and whether the year is a leap-year.

Collapse
mattonem profile image
maxmattone

In one single Smalltalk line, because we can:

2015 asYear months count: [ :m | (m start asDate + 12 days) dayOfWeek = 6 ]. "return 3"
1986 asYear months count: [ :m | (m start asDate + 12 days) dayOfWeek = 6 ]. "return 1"
Collapse
choroba profile image
E. Choroba

Perl solution, using the core library Time::Piece.

#!/usr/bin/perl
use warnings;
use strict;

use Time::Piece;

sub unlucky_days {
    my ($year) = @_;
    return grep $_->fullday eq 'Friday',
           map 'Time::Piece'->strptime("$year-$_-13", '%Y-%m-%d'),
           1 .. 12
}

use Test::More tests => 2;
is unlucky_days(2015), 3, 'year 2015';
is unlucky_days(1986), 1, 'year 1986';

It works because grep in scalar context returns the number of trues.

Collapse
hectorpascual profile image
Héctor Pascual

My python sol :

def unlucky_days(year):
    count = 0
    cal = Calendar()
    for month in range(1,13):
        for day, week_day in cal.itermonthdays2(year, month):
            if day == 13 and week_day == 4:
                count += 1
    return count
Collapse
brightone profile image
Oleksii Filonenko

Elixir:

defmodule Unlucky do
  def days(year) do
    1..12
    |> Enum.map(&Date.from_erl!({year, &1, 13}))
    |> Enum.filter(&(Date.day_of_week(&1) == 5))
    |> Enum.count()
  end
end
Collapse
phallstrom profile image
Philip Hallstrom
require "date"

def unlucky_days(year)
  unlucky = 0
  1.upto(12).each do |month|
    date = Date.new(year, month, 13)
    unlucky += 1 if date.wday == 5
  end
  unlucky
end
Collapse
suchafoka profile image
Suchafoka

Python

import datetime
def unlucky_days(y):
    return len([i for i in range(12) if datetime.date(y,i+1,13).weekday() == 4])