Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CocoaheadsCodeGolf.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
269A58DE20B1822300872989 /* HeatWavesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269A58DD20B1822300872989 /* HeatWavesTests.swift */; };
269A58E020B1822300872989 /* HeatWaves.h in Headers */ = {isa = PBXBuildFile; fileRef = 269A58D220B1822300872989 /* HeatWaves.h */; settings = {ATTRIBUTES = (Public, ); }; };
269A58E820B1823C00872989 /* HeatWaves.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269A58E720B1823C00872989 /* HeatWaves.swift */; };
3448F28C20B80F38008CC209 /* HeatWaves-readable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448F28B20B80F38008CC209 /* HeatWaves-readable.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand All @@ -32,6 +33,7 @@
269A58DF20B1822300872989 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
269A58E720B1823C00872989 /* HeatWaves.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeatWaves.swift; sourceTree = "<group>"; };
269A58ED20B2D13D00872989 /* CharacterCount.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CharacterCount.txt; sourceTree = "<group>"; };
3448F28B20B80F38008CC209 /* HeatWaves-readable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HeatWaves-readable.swift"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -78,6 +80,7 @@
269A58E720B1823C00872989 /* HeatWaves.swift */,
269A58ED20B2D13D00872989 /* CharacterCount.txt */,
269A58D320B1822300872989 /* Info.plist */,
3448F28B20B80F38008CC209 /* HeatWaves-readable.swift */,
);
path = HeatWaves;
sourceTree = "<group>";
Expand Down Expand Up @@ -218,6 +221,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3448F28C20B80F38008CC209 /* HeatWaves-readable.swift in Sources */,
269A58E820B1823C00872989 /* HeatWaves.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
2 changes: 1 addition & 1 deletion HeatWaves/CharacterCount.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
12 bytes.
87 bytes.
100 changes: 100 additions & 0 deletions HeatWaves/HeatWaves-readable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//
// HeatWaves-readable.swift
// HeatWaves
//
// Solution by Udo Borkowski (2018-05-25)
//
// FOR THE PUBLIC DOMAIN
//

// Background
//
// The Royal Netherlands Meteorological Institute defines a heat wave* as a
// series of at least 5 consecutive days of ≥25°C weather (“summery weather”),
// such that at least 3 of those days are ≥30°C (“tropical weather”).
//
// The tropical weather doesn't have to be measured consecutively: for example:
// 30, 25, 30, 26, 27, 28, 32, 30 is a 8-day long heat wave with 4 days of
// tropical weather.
//
// *(Well, by Dutch standards.)
//
// Challenge
//
// Given a non-empty list of positive integers representing Celsius temperature
// measurements from successive days, decide whether that list contains a heat
// wave (as per the above definition).
//
// The shortest answer in bytes wins.
//
// (This function contains the same code/algorithm as 'isHeatWaveIncludedIn'
// in 'HeatWaves.swift' but is intended for a reader who wants to understand
// the code better. So it includes comments, whitespaces, better names, ....)
public func isHeatWaveIncludedIn_readable(waves w: [Int]) -> Bool {

// This solution uses a single array reduce to determine if the array contains
// a heat wave. When the reduce returns 0 we have a heat wave.
//
// The reduced value encodes the number of days ≥25°C (but <30°C) and days ≥30°C found
// so far in the current series.
//
// To encode these two counters in one number we use factors of prim numbers.
//
// (!!!1) When we found a heat wave the reduced value becomes 0.
//
// (!!!2) To represent n days ≥25°C (but <30°C) and m days ≥30°C we use the formula "2^n*3^m"
//
// E.g. 2*3*3*3 = 108 means: 1 day ≥25°C (but <30°C) and 3 days ≥30°C
//
// (!!!3) 2^0*3^0 = 1 means: no days ≥25°C (or ≥30°C)
//

return w.reduce(
1, // initialize the reduce with no days (see !!!3)
{ //
let n = $1 > 24 ? // when the day's temperature was ≥ 25 (*)
$0 * ( // we "increment" the counter by multiplying with the proper factor:
$1>29 ? // when the day's temperature was ≥ 30 (*)
3 // we multiply with 3 (see !!!2)
: // when the day's temperature was < 30 (but ≥ 25)
2) // we multiply with 2 (see !!!2)
: // when the day's temperature was < 25
$0>0 ? // and we have not yet found a heat wave (see !!!1)
1 // we clear the counter to no days (see !!!3)
: // when we have found a heat wave before (see !!!1)
0 // we keep this information, i.e. use 0.
//
// Now let's check if we found a heat wave:
return n % 27 == 0 && // When we have at least 3 days ≥30°C (**)
n > 81 ? // and 2 more days ≥25°C (***)
0 // we have a heat wave and return 0 (see !!!1)
: // Otherwise
n} // we return the count (that may also be 0)
//
)<1 // Finally we just need to check if the result of the reduce is 0
// to determine if we found a heat wave (****)



// (*) instead of "... >= intConst" use "... > intConst-1" to save 1 byte (">=" vs ">")
//
// (**) 3 days ≥30°C means 'n' contains at least the factors 3*3*3 == 27. To check this we
// just need to divide 'n' by 27 and check if the remainder is 0 ("modulo").
//
// (***) We already know we have at least 3 days ≥30°C, i.e. 'a' contains 3*3*3 (see **).
// Now lets check some cases:
//
// | # ≥25°C but <30°C | # ≥30°C | n | isHeatWave? |
// |-------------------+---------+-----+-------------|
// | 0 | 3 | 27 | false |
// | 1 | 3 | 54 | false |
// | 2 | 3 | 108 | true |
// | 0 | 4 | 81 | false |
// | 1 | 4 | 162 | true |
//
// As we can see, when n > 81 (and there are at least 3 days ≥30°C) we have a heat wave.
//
// (****) instead of "== 0"" use "< 0" to save 1 byte ("==" vs "<").
// This transformation is correct as the reduce will only return positive Ints and 0.

}
9 changes: 6 additions & 3 deletions HeatWaves/HeatWaves.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// HeatWaves.swift
// HeatWaves
//
// Created by Sven Titgemeyer on 20.05.18.
// Copyright © 2018 Cocoaheads Aachen. All rights reserved.
// Solution by Udo Borkowski (2018-05-25)
//
// FOR THE PUBLIC DOMAIN
//

// Background
Expand All @@ -25,6 +26,8 @@
// wave (as per the above definition).
//
// The shortest answer in bytes wins.
//
// (see "HeatWaves-readable.swift" for a readable/commented version of this code)
public func isHeatWaveIncludedIn(waves w: [Int]) -> Bool {
return false
return w.reduce(1,{let n=$1>24 ?$0*($1>29 ?3:2):$0>0 ?1:0;return n%27==0&&n>81 ?0:n})<1
}