Advent of Code 2017 Day 5 (part 2) in Functional Programming (FP)

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












I wanted to practice functional programming (fp) without using any library but using vanilla JS only. So I took a problem from Advent of Code (the 2nd part of Day 5):



https://adventofcode.com/2017/day/5




--- Part Two --- Now, the jumps are even stranger: after each jump, if the offset was three or more, instead decrease it by 1. Otherwise,
increase it by 1 as before.



Using this rule with the above example, the process now takes 10
steps, and the offset values after finding the exit are left as 2 3 2
3 -1.



How many steps does it now take to reach the exit?




I'm doing the 2nd part of Day 5. You can only access the 2nd part once you solved the 1st part.



To access the 2nd part type in this number 376976 or check out the solution here: Advent of Code 2017 Day 5 (part 1) in Functional Programming (FP)



First my procedural solution:



 const parsedInput = input => input
.split('n')
.map(c => parseInt(c));

function jumper(maze)
let stepNumber = 0;
let position = 0;
do
const newOffset = maze[position] >= 3 ?
maze[position] - 1 :
maze[position] + 1;
const oldPosition = position;
position = position + maze[position];
maze[oldPosition] = newOffset;
++stepNumber;
while (position < maze.length);
return stepNumber;

console.log("solution ", jumper(parsedInput(INPUT)));


The code above has got more operation than in the first part of this riddle. But it's way faster and shorter than the functional approach of the 1st problem (Advent of Code 2017 Day 5 (part 1) in Functional Programming (FP)).



My FP solution:



 const parsedInput = input => input
.split('n')
.map(c => parseInt(c));

const jumper = input =>
const currentMaze = input.maze;
const currentPosition = input.position;
const currentStepNumber = input.stepNumber;

if (currentPosition >= currentMaze.length)
showAnswer(currentStepNumber);


const newOffset = currentMaze[currentPosition] >= 3 ?
currentMaze[currentPosition] - 1 :
currentMaze[currentPosition] + 1;
const maze = currentMaze
.slice(0, currentPosition)
.concat(newOffset)
.concat(currentMaze.slice(currentPosition + 1));
const position = currentPosition + currentMaze[currentPosition];
const stepNumber = currentStepNumber + 1;
setTimeout(() => jumper(
/*removes call stack -> infinite recursion without built in Tail Call Optimization*/
maze, position, stepNumber
), 0);
;
const showAnswer = res => console.log(res);
const startMaze = parsedInput(INPUT);

jumper(
maze: startMaze,
position: 0,
stepNumber: 0
);


The FP solution is longer and slower. I couldn't solve it without recursion. After a while you hit the stack size. Thanks to Thanks to @Blindman67 he suggested a workaround with setTimeout.



Do you know an FP approach that is faster and shorter than the procedural one?







share|improve this question





















  • your 'procedual' code looks perdy dern functional to me.
    – Occam's Razor
    Jan 15 at 18:48










  • @Iwrestledabearonce. In the first code I used a loop and changed variables. That's not how I understand FP.
    – thadeuszlay
    Jan 15 at 20:36










  • FP is not about not changing variables or avoiding loops, it's about being "decalrative" and not causing side-effects. Just clone maze before operating on it and viola, no side effects. Functions like map, reduce, forEach are, internally, loops anyway.
    – Occam's Razor
    Jan 15 at 20:41










  • if you wanna be trendy you can always assign jumper as an anonymous JS constant.
    – Occam's Razor
    Jan 15 at 20:43






  • 2




    @Iwrestledabearonce. No, I don't want to be "trendy". Never did. Never will. Just improving my skills as a developer.
    – thadeuszlay
    Jan 15 at 20:46
















up vote
0
down vote

favorite












I wanted to practice functional programming (fp) without using any library but using vanilla JS only. So I took a problem from Advent of Code (the 2nd part of Day 5):



https://adventofcode.com/2017/day/5




--- Part Two --- Now, the jumps are even stranger: after each jump, if the offset was three or more, instead decrease it by 1. Otherwise,
increase it by 1 as before.



Using this rule with the above example, the process now takes 10
steps, and the offset values after finding the exit are left as 2 3 2
3 -1.



How many steps does it now take to reach the exit?




I'm doing the 2nd part of Day 5. You can only access the 2nd part once you solved the 1st part.



To access the 2nd part type in this number 376976 or check out the solution here: Advent of Code 2017 Day 5 (part 1) in Functional Programming (FP)



First my procedural solution:



 const parsedInput = input => input
.split('n')
.map(c => parseInt(c));

function jumper(maze)
let stepNumber = 0;
let position = 0;
do
const newOffset = maze[position] >= 3 ?
maze[position] - 1 :
maze[position] + 1;
const oldPosition = position;
position = position + maze[position];
maze[oldPosition] = newOffset;
++stepNumber;
while (position < maze.length);
return stepNumber;

console.log("solution ", jumper(parsedInput(INPUT)));


The code above has got more operation than in the first part of this riddle. But it's way faster and shorter than the functional approach of the 1st problem (Advent of Code 2017 Day 5 (part 1) in Functional Programming (FP)).



My FP solution:



 const parsedInput = input => input
.split('n')
.map(c => parseInt(c));

const jumper = input =>
const currentMaze = input.maze;
const currentPosition = input.position;
const currentStepNumber = input.stepNumber;

if (currentPosition >= currentMaze.length)
showAnswer(currentStepNumber);


const newOffset = currentMaze[currentPosition] >= 3 ?
currentMaze[currentPosition] - 1 :
currentMaze[currentPosition] + 1;
const maze = currentMaze
.slice(0, currentPosition)
.concat(newOffset)
.concat(currentMaze.slice(currentPosition + 1));
const position = currentPosition + currentMaze[currentPosition];
const stepNumber = currentStepNumber + 1;
setTimeout(() => jumper(
/*removes call stack -> infinite recursion without built in Tail Call Optimization*/
maze, position, stepNumber
), 0);
;
const showAnswer = res => console.log(res);
const startMaze = parsedInput(INPUT);

jumper(
maze: startMaze,
position: 0,
stepNumber: 0
);


The FP solution is longer and slower. I couldn't solve it without recursion. After a while you hit the stack size. Thanks to Thanks to @Blindman67 he suggested a workaround with setTimeout.



Do you know an FP approach that is faster and shorter than the procedural one?







share|improve this question





















  • your 'procedual' code looks perdy dern functional to me.
    – Occam's Razor
    Jan 15 at 18:48










  • @Iwrestledabearonce. In the first code I used a loop and changed variables. That's not how I understand FP.
    – thadeuszlay
    Jan 15 at 20:36










  • FP is not about not changing variables or avoiding loops, it's about being "decalrative" and not causing side-effects. Just clone maze before operating on it and viola, no side effects. Functions like map, reduce, forEach are, internally, loops anyway.
    – Occam's Razor
    Jan 15 at 20:41










  • if you wanna be trendy you can always assign jumper as an anonymous JS constant.
    – Occam's Razor
    Jan 15 at 20:43






  • 2




    @Iwrestledabearonce. No, I don't want to be "trendy". Never did. Never will. Just improving my skills as a developer.
    – thadeuszlay
    Jan 15 at 20:46












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I wanted to practice functional programming (fp) without using any library but using vanilla JS only. So I took a problem from Advent of Code (the 2nd part of Day 5):



https://adventofcode.com/2017/day/5




--- Part Two --- Now, the jumps are even stranger: after each jump, if the offset was three or more, instead decrease it by 1. Otherwise,
increase it by 1 as before.



Using this rule with the above example, the process now takes 10
steps, and the offset values after finding the exit are left as 2 3 2
3 -1.



How many steps does it now take to reach the exit?




I'm doing the 2nd part of Day 5. You can only access the 2nd part once you solved the 1st part.



To access the 2nd part type in this number 376976 or check out the solution here: Advent of Code 2017 Day 5 (part 1) in Functional Programming (FP)



First my procedural solution:



 const parsedInput = input => input
.split('n')
.map(c => parseInt(c));

function jumper(maze)
let stepNumber = 0;
let position = 0;
do
const newOffset = maze[position] >= 3 ?
maze[position] - 1 :
maze[position] + 1;
const oldPosition = position;
position = position + maze[position];
maze[oldPosition] = newOffset;
++stepNumber;
while (position < maze.length);
return stepNumber;

console.log("solution ", jumper(parsedInput(INPUT)));


The code above has got more operation than in the first part of this riddle. But it's way faster and shorter than the functional approach of the 1st problem (Advent of Code 2017 Day 5 (part 1) in Functional Programming (FP)).



My FP solution:



 const parsedInput = input => input
.split('n')
.map(c => parseInt(c));

const jumper = input =>
const currentMaze = input.maze;
const currentPosition = input.position;
const currentStepNumber = input.stepNumber;

if (currentPosition >= currentMaze.length)
showAnswer(currentStepNumber);


const newOffset = currentMaze[currentPosition] >= 3 ?
currentMaze[currentPosition] - 1 :
currentMaze[currentPosition] + 1;
const maze = currentMaze
.slice(0, currentPosition)
.concat(newOffset)
.concat(currentMaze.slice(currentPosition + 1));
const position = currentPosition + currentMaze[currentPosition];
const stepNumber = currentStepNumber + 1;
setTimeout(() => jumper(
/*removes call stack -> infinite recursion without built in Tail Call Optimization*/
maze, position, stepNumber
), 0);
;
const showAnswer = res => console.log(res);
const startMaze = parsedInput(INPUT);

jumper(
maze: startMaze,
position: 0,
stepNumber: 0
);


The FP solution is longer and slower. I couldn't solve it without recursion. After a while you hit the stack size. Thanks to Thanks to @Blindman67 he suggested a workaround with setTimeout.



Do you know an FP approach that is faster and shorter than the procedural one?







share|improve this question













I wanted to practice functional programming (fp) without using any library but using vanilla JS only. So I took a problem from Advent of Code (the 2nd part of Day 5):



https://adventofcode.com/2017/day/5




--- Part Two --- Now, the jumps are even stranger: after each jump, if the offset was three or more, instead decrease it by 1. Otherwise,
increase it by 1 as before.



Using this rule with the above example, the process now takes 10
steps, and the offset values after finding the exit are left as 2 3 2
3 -1.



How many steps does it now take to reach the exit?




I'm doing the 2nd part of Day 5. You can only access the 2nd part once you solved the 1st part.



To access the 2nd part type in this number 376976 or check out the solution here: Advent of Code 2017 Day 5 (part 1) in Functional Programming (FP)



First my procedural solution:



 const parsedInput = input => input
.split('n')
.map(c => parseInt(c));

function jumper(maze)
let stepNumber = 0;
let position = 0;
do
const newOffset = maze[position] >= 3 ?
maze[position] - 1 :
maze[position] + 1;
const oldPosition = position;
position = position + maze[position];
maze[oldPosition] = newOffset;
++stepNumber;
while (position < maze.length);
return stepNumber;

console.log("solution ", jumper(parsedInput(INPUT)));


The code above has got more operation than in the first part of this riddle. But it's way faster and shorter than the functional approach of the 1st problem (Advent of Code 2017 Day 5 (part 1) in Functional Programming (FP)).



My FP solution:



 const parsedInput = input => input
.split('n')
.map(c => parseInt(c));

const jumper = input =>
const currentMaze = input.maze;
const currentPosition = input.position;
const currentStepNumber = input.stepNumber;

if (currentPosition >= currentMaze.length)
showAnswer(currentStepNumber);


const newOffset = currentMaze[currentPosition] >= 3 ?
currentMaze[currentPosition] - 1 :
currentMaze[currentPosition] + 1;
const maze = currentMaze
.slice(0, currentPosition)
.concat(newOffset)
.concat(currentMaze.slice(currentPosition + 1));
const position = currentPosition + currentMaze[currentPosition];
const stepNumber = currentStepNumber + 1;
setTimeout(() => jumper(
/*removes call stack -> infinite recursion without built in Tail Call Optimization*/
maze, position, stepNumber
), 0);
;
const showAnswer = res => console.log(res);
const startMaze = parsedInput(INPUT);

jumper(
maze: startMaze,
position: 0,
stepNumber: 0
);


The FP solution is longer and slower. I couldn't solve it without recursion. After a while you hit the stack size. Thanks to Thanks to @Blindman67 he suggested a workaround with setTimeout.



Do you know an FP approach that is faster and shorter than the procedural one?









share|improve this question












share|improve this question




share|improve this question








edited Jan 14 at 22:11
























asked Jan 14 at 21:57









thadeuszlay

435212




435212











  • your 'procedual' code looks perdy dern functional to me.
    – Occam's Razor
    Jan 15 at 18:48










  • @Iwrestledabearonce. In the first code I used a loop and changed variables. That's not how I understand FP.
    – thadeuszlay
    Jan 15 at 20:36










  • FP is not about not changing variables or avoiding loops, it's about being "decalrative" and not causing side-effects. Just clone maze before operating on it and viola, no side effects. Functions like map, reduce, forEach are, internally, loops anyway.
    – Occam's Razor
    Jan 15 at 20:41










  • if you wanna be trendy you can always assign jumper as an anonymous JS constant.
    – Occam's Razor
    Jan 15 at 20:43






  • 2




    @Iwrestledabearonce. No, I don't want to be "trendy". Never did. Never will. Just improving my skills as a developer.
    – thadeuszlay
    Jan 15 at 20:46
















  • your 'procedual' code looks perdy dern functional to me.
    – Occam's Razor
    Jan 15 at 18:48










  • @Iwrestledabearonce. In the first code I used a loop and changed variables. That's not how I understand FP.
    – thadeuszlay
    Jan 15 at 20:36










  • FP is not about not changing variables or avoiding loops, it's about being "decalrative" and not causing side-effects. Just clone maze before operating on it and viola, no side effects. Functions like map, reduce, forEach are, internally, loops anyway.
    – Occam's Razor
    Jan 15 at 20:41










  • if you wanna be trendy you can always assign jumper as an anonymous JS constant.
    – Occam's Razor
    Jan 15 at 20:43






  • 2




    @Iwrestledabearonce. No, I don't want to be "trendy". Never did. Never will. Just improving my skills as a developer.
    – thadeuszlay
    Jan 15 at 20:46















your 'procedual' code looks perdy dern functional to me.
– Occam's Razor
Jan 15 at 18:48




your 'procedual' code looks perdy dern functional to me.
– Occam's Razor
Jan 15 at 18:48












@Iwrestledabearonce. In the first code I used a loop and changed variables. That's not how I understand FP.
– thadeuszlay
Jan 15 at 20:36




@Iwrestledabearonce. In the first code I used a loop and changed variables. That's not how I understand FP.
– thadeuszlay
Jan 15 at 20:36












FP is not about not changing variables or avoiding loops, it's about being "decalrative" and not causing side-effects. Just clone maze before operating on it and viola, no side effects. Functions like map, reduce, forEach are, internally, loops anyway.
– Occam's Razor
Jan 15 at 20:41




FP is not about not changing variables or avoiding loops, it's about being "decalrative" and not causing side-effects. Just clone maze before operating on it and viola, no side effects. Functions like map, reduce, forEach are, internally, loops anyway.
– Occam's Razor
Jan 15 at 20:41












if you wanna be trendy you can always assign jumper as an anonymous JS constant.
– Occam's Razor
Jan 15 at 20:43




if you wanna be trendy you can always assign jumper as an anonymous JS constant.
– Occam's Razor
Jan 15 at 20:43




2




2




@Iwrestledabearonce. No, I don't want to be "trendy". Never did. Never will. Just improving my skills as a developer.
– thadeuszlay
Jan 15 at 20:46




@Iwrestledabearonce. No, I don't want to be "trendy". Never did. Never will. Just improving my skills as a developer.
– thadeuszlay
Jan 15 at 20:46















active

oldest

votes











Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185111%2fadvent-of-code-2017-day-5-part-2-in-functional-programming-fp%23new-answer', 'question_page');

);

Post as a guest



































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes










 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185111%2fadvent-of-code-2017-day-5-part-2-in-functional-programming-fp%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Chat program with C++ and SFML

Function to Return a JSON Like Objects Using VBA Collections and Arrays

Will my employers contract hold up in court?