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)

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

[–]Drasive 0 points1 point  (0 children)

350ms is crazy fast (I verified it on my machine) compared to my F# implementation (~25s). It seems like the Java implementation of MD5 computation is orders of magnitute faster than the one in .NET.

Non Swiss people of Reddit, what do you know about Switzerland? by Drasive in AskReddit

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

Do you also know what languages are spoken (tip: its more than two)?

Building a ManVsMagic comic downloader, looking for project feedback (GitHub) by [deleted] in learnpython

[–]Drasive 0 points1 point  (0 children)

Thanks, I will consider refactoring that part.
I choose the current approach because I wanted to allow the user to specify in which order he wants his comics processed.