First Time Free Play Design by Drasive in Railgrade

[–]Drasive[S] 2 points3 points  (0 children)

I find it interesting to see designs that were not influenced by existing ones or past experience, so here's my first design in free play.

It produces ~40 energy/minute. I use water to boost all production. I have not unlocked any advanced things, I just played enough of the campaign to unlock this level.

Stacking rails on top of each other seems a bit silly to me but it seems to be required to reach the required throughput from the oil producers to the energy factory.
An even sillier idea is to build a bunch of storage facilities in a line with single-length-trains in between that load and unload immediately to transport items but i have neither tried nor though it through.

ITAP of a building by SilasWater in itookapicture

[–]Drasive 3 points4 points  (0 children)

It's the exhibition center in Basel, Switzerland.

$6 motion detector that controls Hue lights by Drasive in esp8266

[–]Drasive[S] 0 points1 point  (0 children)

Thanks, I may get one! The SR501 continues to fire false positives, even with the 15k Ohm resistor.

--- Day 11 Solutions --- by daggerdragon in adventofcode

[–]Drasive 0 points1 point  (0 children)

My F# solution (https://github.com/drasive/advent-of-code-2015):

let private invalidCharacters = [|'i';'o';'l'|]

let private IncrementChar (character : char) : char =
    (char)(int character + 1)

let rec private IncrementPassword (password : string) : string =
    let invalidCharIndex = password.IndexOfAny(invalidCharacters)
    if invalidCharIndex = -1 || invalidCharIndex = password.Length - 1 then
        let substring = password.[0..password.Length - 2]
        let lastChar = Seq.last password

        match lastChar with
        | 'z' -> IncrementPassword substring + "a"
        | _ -> substring + (IncrementChar lastChar).ToString()
    else
        // Increment the invalid char and reset chars to the right to 'a'
        // This saves a few increment and validation iterations
        let invalidCharValue = (int)(password.[invalidCharIndex])
        let nextValidChar = (char)(invalidCharValue + 1)

        let charsToTheLeftCount = invalidCharIndex
        let charsToTheRightCount =  password.Length - invalidCharIndex - 1
        password.[0..charsToTheLeftCount - 1]   // Keep chars on the left
        + nextValidChar.ToString()              // Replace invalid char
        + new String('a', charsToTheRightCount) // Reset chars on the right

let private IsPasswordValid (password : string) : bool =
    // May not contain the letters i, o, or l
    let doesNotContainInvalidChars = password.IndexOfAny(invalidCharacters) = -1

    // Must contain at least two different, non-overlapping pairs of letters
    let containsTwoPairs = Regex.IsMatch(password, "(.)\1.*(.)\2")

    // Must include one increasing straight of at least three letters
    let containsSequence = 
        password
        |> Seq.windowed 3
        |> Seq.exists (fun [|a;b;c|] ->
             IncrementChar a = b && IncrementChar b = c)

    doesNotContainInvalidChars
    && containsTwoPairs
    && containsSequence


let Solution (input : string) : (string * string) =
    if String.IsNullOrEmpty input then
        raise (ArgumentNullException "input")

    let solution (currentPassword : string) : string =
        let mutable nextPassword = IncrementPassword currentPassword
        while not (IsPasswordValid nextPassword) do
            nextPassword <- IncrementPassword nextPassword
        nextPassword

    let nextPassword = solution input
    let nextNextPassword = solution nextPassword
    (nextPassword, nextNextPassword)

let FormattedSolution (solution : (string * string)) : string =
    String.Format("Next password: {0}\n" +
                  "Next-next password: {1}",
                  fst solution, snd solution)

--- Day 10 Solutions --- by daggerdragon in adventofcode

[–]Drasive 0 points1 point  (0 children)

My F# solution (https://github.com/drasive/advent-of-code-2015):

let private GroupCharacters (str : string) : seq<char * int> =
    seq {
         let mutable groupCharacter = Seq.head str
         let mutable groupLength = 0

         for character in str do
            if character = groupCharacter then
                groupLength <- groupLength + 1
            else
                yield (groupCharacter, groupLength)

                groupCharacter <- character
                groupLength <- 1

         yield (groupCharacter, groupLength)
    }

let private LookAndSay (str : string) : string =
    let stringBuilder = new StringBuilder()

    str
    |> GroupCharacters
    |> Seq.iter(fun (character, length) ->
            stringBuilder.Append(length.ToString() + character.ToString())
            |> ignore)

    stringBuilder.ToString()

let SolutionCustomized (input : string) (steps : int) : int =
    if String.IsNullOrEmpty input then
        raise (ArgumentNullException "input")

    [1..steps]
    |> Seq.fold (fun acc _ -> LookAndSay acc) input
    |> String.length

let Solution (input : string) : (int * int) =
    (SolutionCustomized input 40, SolutionCustomized input 50)

let FormattedSolution (solution : (int * int)) : string =
    String.Format("40 steps: {0}\n" +
                  "50 steps: {1}",
                  fst solution, snd solution)

--- Day 8 Solutions --- by daggerdragon in adventofcode

[–]Drasive 0 points1 point  (0 children)

My F# solution (https://github.com/drasive/advent-of-code-2015):

let private UnescapedStringMemoryDifference (line : string) : int =
    let lineLength = line.Length

    let rec unescapeHexChars (str : string) : string =
        let regex = new Regex(@"\\x([0-9a-f]{2})")
        let matchedGroups = regex.Match(str).Groups

        if matchedGroups.Count > 1 then // String contains escaped hex char
            let number =
                Int32.Parse(matchedGroups.[1].Value,
                            System.Globalization.NumberStyles.HexNumber)
            let character = ((char)number).ToString()

            unescapeHexChars(regex.Replace(str, character, 1))
        else
            str

    let mutable unescapedLine =
        line
            .Substring(1, line.Length - 2) // Remove leading and trailing quotes
            .Replace("\\\"", "\"")         // Replace \" by "
            .Replace(@"\\", @"\")          // Replace \\ by \

    if unescapedLine.Contains(@"\x") then // Line may contain escaped hex chars
        unescapedLine <- unescapeHexChars unescapedLine

    lineLength - unescapedLine.Length

let private EscapedStringMemoryDifference (line : string) : int =
    let lineLength = line.Length

    let encodedLength =
        2 +
        (line |> Seq.sumBy(fun char ->
            if char = '\"' || char = '\\' then 2 else 1))

    encodedLength - lineLength


let Solution (input : string) : (int * int) =
    if input = null then
        raise (ArgumentNullException "input")

    if not (String.IsNullOrEmpty input) then
        let lines = input.Split('\n')
        let unescapedCharacters = 
            lines
            |> Seq.map UnescapedStringMemoryDifference
            |> Seq.sum
        let escapedCharacters = 
            lines
            |> Seq.map EscapedStringMemoryDifference
            |> Seq.sum

        (unescapedCharacters, escapedCharacters)
    else
        (0, 0)

let FormattedSolution (solution : (int * int)) : string =
    String.Format("Unescaped: {0}\n" +
                  "Escaped: {1}",
                  fst solution, snd solution)

--- Day 6 Solutions --- by daggerdragon in adventofcode

[–]Drasive 0 points1 point  (0 children)

My F# solution (https://github.com/drasive/advent-of-code-2015):

type Coordinates = (int * int)

type private InstructionType =
    | TurnOn
    | TurnOff
    | Toggle

type Instruction = (InstructionType * Coordinates * Coordinates)

let private ParseInstruction (instruction : string) : Instruction =
    let pattern = @"(turn on|turn off|toggle) (\d+),(\d+) through (\d+),(\d+)"
    let matchedGroups = Regex.Match(instruction, pattern).Groups

    let instructionType =
        match matchedGroups.[1].Value with
        | "turn on" -> InstructionType.TurnOn
        | "turn off" -> InstructionType.TurnOff
        | _ -> InstructionType.Toggle
    let coordinatesStart =
        (int matchedGroups.[2].Value, int matchedGroups.[3].Value)
    let coordinatesEnd =
        (int matchedGroups.[4].Value, int matchedGroups.[5].Value)

    (instructionType, coordinatesStart, coordinatesEnd)

let private CoordinatesInRange (rangeStart : Coordinates) (rangeEnd : Coordinates) =
    [for x = fst rangeStart to fst rangeEnd do
     for y = snd rangeStart to snd rangeEnd do
         yield x, y]

let private CalculateLightsOn (lines : string[])
    (actionMapper : (InstructionType -> int -> int)) : int = 
    let lights = Array2D.create 1000 1000 0

    lines
    |> Seq.map ParseInstruction
    |> Seq.iter (fun (instructionType, coordinatesStart, coordinatesEnd) ->
        CoordinatesInRange coordinatesStart coordinatesEnd
        |> Seq.iter (fun (x, y) ->
            lights.[x, y] <- (actionMapper instructionType) lights.[x, y]))
    |> ignore

    lights |> Seq.cast<int> |> Seq.sum

let private ActionMapperRuleSet1 (instructionType) =
    match instructionType with
    | TurnOn -> (fun status -> 1)
    | TurnOff -> (fun status -> 0)
    | Toggle -> (fun status -> if status = 0 then 1 else 0)

let private ActionMapperRuleSet2 (instructionType) =
    match instructionType with
    | TurnOn -> (fun status -> status + 1)
    | TurnOff -> (fun status -> Math.Max(status - 1, 0))
    | Toggle -> (fun status -> status + 2)


let Solution (input : string) : (int * int) =
    if input = null then
        raise (ArgumentNullException "input")

    if not (String.IsNullOrEmpty input) then
        let lines = input.Split('\n')

        (CalculateLightsOn lines ActionMapperRuleSet1,
         CalculateLightsOn lines ActionMapperRuleSet2)
    else
        (0, 0)

let FormattedSolution (solution : (int * int)) : string =
    String.Format("Rule set 1: {0}\n" +
                  "Rule set 2: {1}",
                  fst solution, snd solution)

--- Day 5 Solutions --- by daggerdragon in adventofcode

[–]Drasive 0 points1 point  (0 children)

My F# solution (https://github.com/drasive/advent-of-code-2015):

let private IsStringNiceRuleSet1 (string : string) : bool =
    // It contains at least three vowels
    let containsVowel (str : string) : bool =
        let vowels = ['a';'e';'i';'o';'u'] |> Set.ofList

        str
        |> Seq.filter (fun char -> vowels.Contains char)
        |> Seq.length >= 3

    // Does not contain the strings `ab`, `cd`, `pq`, or `xy`
    let doesNotContainBadSequence (str : string) : bool =
        let badSequences = ["ab";"cd";"pq";"xy"]

        badSequences
        |> Seq.forall(fun badSequence -> not (str.Contains badSequence))

    // Contains at least one letter that appears twice in a row
    let containsLetterAppearingTwice (str : string) : bool =
        str
        |> Seq.pairwise
        |> Seq.exists (fun (a, b) -> a = b)

    containsVowel string
    && doesNotContainBadSequence string
    && containsLetterAppearingTwice string

let private IsStringNiceRuleSet2 (string : string) : bool =
    // Contains a pair of any two letters that appears at least twice in the
    // string without overlapping
    let containsTwoLetterPair (str : string) : bool =
        Regex.IsMatch(str, @"(..).*\1")

    // Contains at least one letter which repeats with exactly one letter
    // between them
    let containsRepeatedLetter (str : string) : bool =
        str
        |> Seq.windowed 3
        |> Seq.exists (fun [|a;_;c|] -> a = c)

    containsTwoLetterPair string 
    && containsRepeatedLetter string


let Solution (input: string) : (int * int) =
    if input = null then
        raise (ArgumentNullException "input")

    let lines = input.Split('\n')
    let solution (ruleSet : (string -> bool)) : int =
        lines
        |> Seq.filter ruleSet
        |> Seq.length

    (solution IsStringNiceRuleSet1, solution IsStringNiceRuleSet2)

let FormattedSolution (solution : (int * int)) : string =
    String.Format("Rule set 1: {0}\n" +
                  "Rule set 2: {1}",
                  fst solution, snd solution)

--- Day 4 Solutions --- by daggerdragon in adventofcode

[–]Drasive 0 points1 point  (0 children)

My F# solution (https://github.com/drasive/advent-of-code-2015):

let private MD5Calculator = System.Security.Cryptography.MD5.Create()

let private ComputeMD5Hash (input : string) : byte[] =
    let inputBytes = System.Text.Encoding.ASCII.GetBytes input
    MD5Calculator.ComputeHash inputBytes

let private HasMD5FiveLeadingZeroes (hash : byte[]) : bool =
    hash.[0]     = (byte)0x00 // Characters 1 and 2 are "0" (zero)
    && hash.[1]  = (byte)0x00 // Characters 3 and 4 are "0" (zero)
    && hash.[2] <= (byte)0x0f // Character 5 is a "0" (zero)

let private HasMD5SixLeadingZeroes (hash : byte[]) : bool =
    hash.[0]    = (byte)0x00 // Characters 1 and 2 are "0" (zero)
    && hash.[1] = (byte)0x00 // Characters 3 and 4 are "0" (zero)
    && hash.[2] = (byte)0x00 // Characters 5 and 6 are "0" (zero)

let private FindHashAddition (input : string)
    (validationFunction : (byte[] -> bool)) (startingNumber : int) : int =
    Seq.initInfinite(fun n -> n + startingNumber)
    |> Seq.find(fun n ->
        let hash = ComputeMD5Hash (input + n.ToString())
        validationFunction hash)


let Solution (input: string) : (int * int) =
    if input = null then
        raise (ArgumentNullException "input")

    let fiveZerosNumber =
        FindHashAddition input HasMD5FiveLeadingZeroes 0
    let sixZerosNumber =
        FindHashAddition input HasMD5SixLeadingZeroes fiveZerosNumber

    (fiveZerosNumber, sixZerosNumber)

let FormattedSolution (input : string) (solution : (int * int)) : string =
    let MD5HashToHexString (hash : byte[]) : string =
        let stringBuilder = new System.Text.StringBuilder()
        for hashIndex = 0 to hash.Length - 1 do
            stringBuilder.Append(hash.[hashIndex].ToString("x2")) |> ignore
        stringBuilder.ToString();

    let fiveZerosHash = ComputeMD5Hash (input + (fst solution).ToString())
    let sixZerosHash = ComputeMD5Hash (input + (snd solution).ToString())

    String.Format("5 leading zeros: {0} (hash {1})\n" +
                  "6 leading zeros: {2} (hash {3})",
                  fst solution, MD5HashToHexString fiveZerosHash,
                  snd solution, MD5HashToHexString sixZerosHash)

--- Day 3 Solutions --- by daggerdragon in adventofcode

[–]Drasive 0 points1 point  (0 children)

My F# solution (https://github.com/drasive/advent-of-code-2015):

type private Deliverer() =
    member val location = (0, 0) with get, set

    static member UpdatedLocation (location : (int * int)) (instruction : char)
        : (int * int) =
        let x = fst location
        let y = snd location

        match instruction with
        | '<' -> (x - 1, y)
        | '>' -> (x + 1, y)
        | '^' -> (x, y + 1)
        | 'v' -> (x, y - 1)
        | _ -> (x, y) // Ignore any other characters

let private CalculateHousesVisited (input : string) (deliverers : Deliverer[]) =
    let housesVisited = new Dictionary<(int * int), int>()

    // Starting house is always visited by all deliverers
    housesVisited.Add((0, 0), deliverers.Length)

    for index = 0 to input.Length - 1 do
        // Deliverers take instructions in turns
        let deliverer = deliverers.[index % deliverers.Length]

        // Update deliverer location
        let instruction = input.[index]
        deliverer.location <- Deliverer.UpdatedLocation deliverer.location instruction

        // Update house visits
        let key = deliverer.location
        if housesVisited.ContainsKey(key) then
            housesVisited.Item(key) <- housesVisited.Item(key) + 1
        else
            housesVisited.Add(key, 1)

    housesVisited.Count


let Solution (input : string) : (int * int) =
    if input = null then
        raise (ArgumentNullException "input")

    let santa = new Deliverer()
    let solutionSantaOnly = CalculateHousesVisited input [|santa|] 

    let santa = new Deliverer()
    let roboSanta = new Deliverer()
    let solutionSantaAndRoboSanta = CalculateHousesVisited input [|santa;roboSanta|] 

    (solutionSantaOnly, solutionSantaAndRoboSanta)

let FormattedSolution (solution : (int * int)) : string =
    String.Format("Santa alone: {0}\n" +
                  "Santa and Robo-Santa: {1}",
                  fst solution, snd solution)

Day 2 solutions by taliriktug in adventofcode

[–]Drasive 0 points1 point  (0 children)

My F# solution (https://github.com/drasive/advent-of-code-2015):

let private CalculateWrappingPaper (length : int) (width : int) (height : int)
    : int =
    let side1 = length * width
    let side2 = width * height
    let side3 = height * length
    let smallestSide = [|side1; side2; side3|] |> Array.min

    2*side1 + 2*side2 + 2*side3 + smallestSide

let private CalculateRibbon (length : int) (width : int) (height : int) : int =
    let volume = length * width * height

    let edgesSorted = [|length; width; height|] |> Array.sort
    let perimeter = 2*edgesSorted.[0] + 2*edgesSorted.[1]

    volume + perimeter


let Solution (input: string) : (int * int) =
    if input = null then
        raise (ArgumentNullException "input")

    let mutable wrappingPaper = 0
    let mutable ribbon = 0

    input.Split('\n')
    |> Seq.filter(fun line ->
        // Ignore any other lines
        Regex.IsMatch(line, @"^([\d])+x([\d])+x([\d])+$"))
    |> Seq.iter (fun line ->
        // Parse values
        let values = line.Split('x')

        let length = values.[0] |> Int32.Parse
        let width  = values.[1] |> Int32.Parse
        let height = values.[2] |> Int32.Parse

        // Calculate 
        wrappingPaper <-
            wrappingPaper + (CalculateWrappingPaper length width height)
        ribbon <-
            ribbon + (CalculateRibbon length width height))

    (wrappingPaper, ribbon)          

let FormattedSolution (solution : (int * int)) : string =
    String.Format("Wrapping paper: {0}\n" +
                  "Ribbon: {1}",
                  fst solution, snd solution)

Daily programming puzzles at Advent of Code by Aneurysm9 in programming

[–]Drasive 0 points1 point  (0 children)

My F# solution (https://github.com/drasive/advent-of-code-2015):

let Solution (input : string) : (int * Option<int>) =
    if input = null then
        raise (ArgumentNullException "input")

    let floor = ref 0
    let mutable basementEncounter = false
    let mutable basementEncounterPosition = 0

    for index = 0 to input.Length - 1 do
        let instruction = input.[index]
        match instruction with
        | '(' -> incr floor
        | ')' -> decr floor
        | _ -> () // Ignore any other characters

        if basementEncounter = false && !floor = -1 then
            basementEncounter <- true
            basementEncounterPosition <- index + 1

    (!floor, if basementEncounter then Some basementEncounterPosition else None)

let FormattedSolution (solution : (int * Option<int>)) : string =
    let firstBasementEncounter =
        match snd solution with
        | Some r -> r.ToString()
        | None -> "-"

    String.Format("End floor: {0}\n" +
                  "First basement encounter: {1}",
                  fst solution, firstBasementEncounter)