text:
Help Pac-Man count the Pac-Dots
On the advice of Ms. Pac-Man who's worried about him getting overweight, Pac-Man has decided to keep track of his daily Pac-Dot intake. Help him count the number of Pac-Dots on a given path in the maze!
The maze

To help you build your own encoding of the maze, you can get some raw data here.
Pac-Man's journey
In the context of this challenge, the following rules apply:

First, the good news: the ghosts aren't there.
Pac-Man always starts his race at the position indicated on the above picture, heading to the East. There is no Pac-Dot at the starting position.
As long as he's following a straight path, he keeps advancing to the next squares.
When he encounters a 90° turn without any other available path (orange squares on the map), he automatically and systematically takes the turn.
When he encounters a junction where several paths are available (green squares on the map), he may either continue on the same direction -- if applicable -- or choose another direction (including doing a U-turn).
When Pac-Man passes through one of the exits on the middle left or middle right side of the maze, he immediately reappears on the opposite side.
Pac-Man eats all the Pac-Dots on the path he's following. Once a Pac-Dot has been eaten, it is removed from the maze.

The challenge
Input
You'll be given a string describing Pac-Man's behavior on the junctions that he's going to reach. This string will be made of the following characters:

L: do a 90° turn to the left
R: do a 90° turn to the right
F: go forwards (no direction change)
B: go backwards (do a U-turn)

When all characters have been processed, Pac-Man stops at the next junction he encounters.
Output
You have to print or output the number of Pac-Dots eaten along the input path.
Rules

You can write a full program or a function.
You can take input in either uppercase or lowercase, as either a string or an array of characters. You may also use other characters (but only one character per direction) or integers in [0 .. 9]. If you do so, please specify it clearly in your answer.
You can assume that the input is always valid. (The jsFiddle below will detect errors, but you're not supposed to.)
This is code-golf, so the shortest code in bytes wins.
Standard loopholes are forbidden.

Hint
It may not be required nor optimal to store the exact shape of the maze.
Test cases and demo
The following test cases -- or any other input -- can be tested in this jsFiddle.
1. Input  : ""
   Output : 1
   Comment: Pac-Man just advances to the first junction, eats the Pac-Dot on it and stops.

2. Input  : "L"
   Output : 7

3. Input  : "FFR"
   Output : 13

4. Input  : "LFLR"
   Output : 17
   Comment: Pac-Man will exit on the middle right side and re-appear on the left side.

5. Input  : "BBBB"
   Output : 2

6. Input  : "BRRFFFL"
   Output : 15

7. Input  : "LFFRLFFFFRF"
   Output : 50

8. Input  : "BRFRLRFRLFR"
   Output : 54
   Comment: Pac-Man will exit on the middle left side and re-appear on the right side.

9. Input  : "FFLRLFFLLLLFFBFLFLRRRLRRFRFLRLFFFLFLLLLFRRFBRLLLFBLFFLBFRLLR"
   Output : 244
   Comment: All cleared!

Here's some more data to help out: https://pastebin.com/G4MnbVww . It's a list of every junction and the number of pac-dots on the road to the next junction depending on which direction you go (0=up, 1=left, 2=down, 3=right). There might be some errors, and keep in mind that junctions 12, 13, 15, 16, 18, and 19 have no dot in the middle, while all the others do.

@Challenger5 This is looking good. Because the moves are relative, you'd probably want to also keep track of the new orientation of Pac-Man when the next junction is reached, though.

BTW In the game pac man cannot do a u-turn

@SIGSEGV By 'u-turn', I just mean changing to the opposite direction, which is possible at any time in the original arcade game and all the clones I know. Should I use another term?

I'm pretty sure Pac-Man started heading left in the arcade game, not right.

@mbomb007 Yes, you are right. I shouldn't have relied on my aging memory and checked that only after posting. (Not that it changes anything to the challenge. ^^)

"You may also use other characters" - Can we use '\0', (char)1, (char)2, (char)3 instead of FLBR?

@ngn Do you mean NUL, SOH, STX, ETX? That's kinda unexpected but doesn't infringe the rules. So, yes. Digits would be fine as well (updated).

Yes, that's what I meant. Thanks.

Pyth, 356 345 + 1 = 346 bytes
The code contains some unprintables, so here is the reversible xxd hexdump.
0000000: 4a4b 304c 2c3d 2b4b 4062 4a58 624a 3041  JK0L,=+K@bJXbJ0A
0000010: 2c63 6a43 2201 e120 49b4 efbc e267 27f4  ,cjC".. I....g'.
0000020: a11b f5d5 7f79 d1a0 ab8a 7689 449f 0c50  .....y....v.D..P
0000030: b2d4 7c30 99c3 368e aa67 4213 ab9b d276  ..|0..6..gB....v
0000040: d75f 6e99 5757 04a6 08cc 99d0 7141 3d2f  ._n.WW......qA=/
0000050: d854 7cf7 4a70 954e 6e35 f9b9 e0c5 1d53  .T|.Jp.Nn5.....S
0000060: 36d5 63f9 cf13 0f66 c113 4dec 956e 5225  6.c....f..M..nR%
0000070: b14a 1659 dcb5 6822 3534 2034 6a43 2203  .J.Y..h"54 4jC".
0000080: ffe3 8fff 2232 3d59 636a 4322 0b8a 4624  ...."2=YcjC"..F$
0000090: 7815 4a94 192c 79f6 d6e5 e098 5e97 76bc  x.J..,y.....^.v.
00000a0: 23cf 027c 35c5 5098 2a83 68f1 823a 83f6  #..|5.P.*.h..:..
00000b0: dfa4 7e12 443f 0257 7adb ab2d 8e6f 1199  ..~.D?.Wz..-.o..
00000c0: 9a3e 3f9d a524 d331 c5ff 94ae e5a2 3507  .>?..$.1......5.
00000d0: bd22 3334 2032 3d6b 2b30 6a43 2202 25f2  ."34 2=k+0jC".%.
00000e0: f55c 2252 c250 0002 c250 0000 065c 225c  .\"R.P...P...\"\
00000f0: 2247 5289 3698 4227 5350 8822 3136 3d64  "GR.6.B'SP."16=d
0000100: 636a 4322 8223 a80e 5c22 981d d272 729d  cjC".#..\"...rr.
0000110: d88d 981d 5c22 5c22 2bd7 91dd 9428 73d7  ....\"\"+....(s.
0000120: 1dd7 2234 2032 5651 2079 483d 547e 4a40  .."4 2VQ yH=T~J@
0000130: 4047 4a2b 5a78 2246 5242 4c22 4e20 796b  @GJ+Zx"FRBL"N yk
0000140: 3d5a 4040 647e 4a40 4059 4a3d 5421 7840  =Z@@d~J@@YJ=T!x@
0000150: 594a 5454 2968 7948 0a                   YJTT)hyH.

Requires the -M flag to disable memoization. Unfortunately, this can't be done in any online executor I know of.
Here is a readable printable ASCII version:
JK0L,=+K@bJXbJ0A,cj746957013238413906925468440008893181365431681519974815772691846219267045007717553452313017550830370829477591340658010575885616582299429376501117428763541235628345630376341520044712982918668584832091126800263024965443560007480163218792 54 4j17178005503 2=Ycj664551201217474826979459068682259492333017695780569003557724234375880492114440213266014621594427584622393511454741615093293082181365458295035985321888753898774398909 34 2=k+0j883734055588186287049718559289059922762611092840989558085734536 16=dcj53536195844172273707047543644202986760006840011986146398708374999 4 2VQ yH=T~J@@GJ+Zx"FRBL"N yk=Z@@d~J@@YJ=T!x@YJTT)hyH

Explanation
This is very much work in progress, so I won't post a complete explanation yet.
Basically, the program represents the board as a (somewhat weird) graph using five lookup tables: 2 for connectivity, 1 for junction directions, and 2 for dot counts. This was built by a 200-line Python script I spent way too many hours on. Then the program just walks through the input and counts the dots, updating the dot tables to zero as the dots are collected.
TODO:

Write Python routine for reordering the nodes until the lookup table contains as few escape-requiring characters as possible
Try to remove section handling altogether (should remove one lookup table)

UPDATE: tried this, seems to not remove the table and lengthen code

Rewrite Pyth-side logic (the current one isn't very golfed)

UPDATE: somewhat done, code's still imperfect

Why don't you just generate the URL so that you can run the real code on TIO? Maybe Dennis should add an easier way to do that.

@mbomb007 TIO doesn't support test suites (for Pyth, anyway), so I like to use Pyth's own host. Also, I'm not very confident with browsers handling null bytes correctly.

For the non-test suite, you could. And you can still code with nulls, you just can't copy/paste them, which is why you have to generate the URL.

Longest Pyth answer yet?

@LuisMendo At least for me, based on a quick search. :~)

k, 264 bytes
b:,/16 16\'108_a:-135#0+1:"p.k"
(#(?27,r 1)^(12+!8)^14 17)+/b@?*|r:+1 27 0{i:a?64/(4!2+y+*x;x 1);(4 64\a i+1-2*2!i),_i%2}\0:""
\
...binary data...

Hex dump:
$ xxd p.k
00000000: 623a 2c2f 3136 2031 365c 2731 3038 5f61  b:,/16 16\'108_a
00000010: 3a2d 3133 3523 302b 313a 2270 2e6b 220a  :-135#0+1:"p.k".
00000020: 2823 283f 3237 2c72 2031 295e 2831 322b  (#(?27,r 1)^(12+
00000030: 2138 295e 3134 2031 3729 2b2f 6240 3f2a  !8)^14 17)+/b@?*
00000040: 7c72 3a2b 3120 3237 2030 7b69 3a61 3f36  |r:+1 27 0{i:a?6
00000050: 342f 2834 2132 2b79 2b2a 783b 7820 3129  4/(4!2+y+*x;x 1)
00000060: 3b28 3420 3634 5c61 2069 2b31 2d32 2a32  ;(4 64\a i+1-2*2
00000070: 2169 292c 5f69 2532 7d5c 303a 2222 0a5c  !i),_i%2}\0:"".\
00000080: 0a02 4005 c006 4109 c103 8008 8143 c244  ..@...A......C.D
00000090: c345 c446 c547 c648 c749 c84a 820a 830c  .E.F.G.H.I.J....
000000a0: 840d 870b 8889 cb0e 8a11 8b0f 4c4d cc10  ............LM..
000000b0: cd4e d14f ce51 d014 8e12 8f13 9017 9153  .N.O.Q.........S
000000c0: d215 9216 931e 5455 d41a d51b 5657 d61f  ......TU....VW..
000000d0: d718 941d 9759 d85a d95b da5c db5d dc98  .....Y.Z.[.\.]..
000000e0: de20 9921 9c5f 9d5e 60df e161 e089 9833  . .!._.^`..a...3
000000f0: 4222 2247 2662 7550 0000 0500 5000 c255  B""G&buP....P..U
00000100: 2c22 2202 2588 5ff2                      ,"".%._.

The binary data at the end encodes two arrays:

a consists of pairs of bytes, each representing (64*direction)+junctionId

b is the number of Pacman dots between each pair of junctions in a

The program reads its own source file (p.k) and decodes the data.
The input comes from stdin and uses 0x00,0x01,0x02,0x03 (a.k.a. NUL,SOH,STX,ETX - the first four ASCII codes) instead of FLBR.
I use my own implementation of k which is limited, bloated, crashy, and slow compared to the real thing. I test with the following program:
t:{e:($y),"\n"; a:`sys[("/path/to/k";"./p.k");`c$"FLBR"?x]
   1@$[a~e;"ok\n";"failed ",x,"\n expected: ",e," actual: ",a,"\n"];}
t["";1]
t[,"L";7]
t["FFR";13]
t["LFLR";17]
t["BBBB";2]
t["BRRFFFL";15]
t["LFFRLFFFFRF";50]
t["BRFRLRFRLFR";54]
t["FFLRLFFLLLLFFBFLFLRRRLRRFRFLRLFFFLFLLLLFRRFBRLLLFBLFFLBFRLLR";244]
\

I compiled an interpreter for Linux (sorry, no Windows) and put the necessary files to run the tests here: https://github.com/ngn/tmp  To run them, just type: ./k t.k  If you still do need a download link for p.k: https://github.com/ngn/tmp/blob/master/p.k?raw=true


text:
Never odd or even
Did you notice, that this is a palindrome?
Input
Non-negative integer number or string representing it
Output
4 possible outputs, representing two properties of number:

is it palindrome
tricky #2

Tricky #2 property
If number is not palindrome, this property answers the question "Do the first and the last digits have the same parity?"
If number is palindrome, this property answers the question "Do the first and middle digit have the same parity?". For even lengths, the middle digit is one of the center two digits.
Examples

12345678 -> False False
  It is not palindrome, first and last digits have different parity
12345679 -> False True
  It is not palindrome, first and last digits have same parity
12344321 -> True False
  It is palindrome, the first digit 1 and middle digit 4 have different parity
123454321 -> True True
  It is palindrome, the first digit 1 and middle digit 5 have same parity

P.S.
You are up to decide output type and format. It could be any 4 distinct values. Just mention it in your answer.

It's not clear what "this number's half" means. I thought it meant n/2, but the clarification seems to imply it's the first or last half stringwise.

@xnor Its stringwise

I've edited in what I think is a simpler way to state the rule.

@xnor Seems good, thank you!

Can we assume non-negative integer input?

@Titus Yeah, I guess so. I'll add this to post

05AB1E, 15, 14 13 bytes (Thanks to Riley and carusocomputing)
ÐRQi2ä¨}È¹RÈQ

Try online
Returns with brackets if it is a palindrome
Returns with 0 if the parity is different, 1 if it is the same
Ð Add input, such that I have enough input to work with
R Reverse the last element of the stack
Q Look if it is the same (takes the two top elements and performs ==)
i If statement, so only goes through when it is a palindrome
2 Push the number 2
ä Split the input in 2 equal slices
¨ Push the first element of the split (1264621 results in 1264)
} End if
È Check if last element is even
¹ Push the first input again
R Reverse that input
È Check if it is even now
Q Check if those even results are the same and implicitly print

Will you put some explanation of your code?

Will do really soon

You could use ¨ instead of 1£.

You don't need the ending ,, implicit output. Also instead of 2ä you can use bifurcate: Â; savings of 2 bytes for 12: ÐRQiÂ¨}È¹RÈQ

I'd test the bifurcate part, it behaves weirdly in certain scenarios, but that , should push you into the lead ;).

The bifurcate does not work, the ending is indeed a bytesaver. Thanks!

In your explanation, you need to replace 1 with ¨ I think. Also, technically, ¨ means a[:-1].

PHP, 55 52 bytes
echo$p=strrev($n=$argn)==$n,$n-$n[$p*log($n,100)]&1;

takes input from STDIN; run with -R.
output:

10  for palindrome and same parity
11 for palindrome and different parity
0 for non-palindrome and same parity
1 for non-palindrome and different parity

notes:

strlen($n)/2 == log($n,10)/2 == log($n,100)
if palindrome, compare middle digit $n[1*log($n,100)]
if not, first digit $n[0*log($n,100)]
... to whole number (<- lowest bit <- last digit)

You could save one byte by using <?= instead of echo http://sandbox.onlinephpfunctions.com/code/f2f7a31a4ec489e86f15515a128f8430a9c51beb

@roberto06 $argn is only defined with -R, and that doesn´t allow tags.

OK, didn't know that, thanks.

@roberto06 Wait ... $argn is also available with -F. But nm.

Jelly, 16 14 bytes
DµŒḂṄHC×LĊị+ḢḂ

Try it online!
Outputs two lines:

1 for palindrome, 0 for not
0 for tricky #2, 1 for not

Explanation
DµŒḂṄHC×LĊị+ḢḂ    Main link. Argument: n (number)
D                 Get the digits of n
 µ                Start a new monadic chain
  ŒḂ              Check if the digit array is a palindrome (1 if yes, 0 if no)
    Ṅ             Print the result with a newline
     H            Halve (0.5 if palindrome, 0 if not)
      C           Subtract from 1 (0.5 if palindrome, 1 if not)
       ×          Multiply by...
        L         ...length of array (length/2 if palindrome, length if not)
         Ċ        Round up
          ị       Take item at that index from the digits
           +      Add...
            Ḣ     ...first item of digits
             Ḃ    Result modulo 2

I always ask myself, how many different characters do you have to learn to be able to write programs with this? Do you know all the meaning and all the characters? Can you even type the characters without using ALT key or character table? What does an IDE for this look like?

@DanFromGermany I don't remember most of the characters yet. Because of that I also haven't got to learning the US International keyboard layout, so I just copy the characters from the wiki. Development happens by trial-and-error in TIO.

Python 2, 70 68 66 bytes
lambda n:(n==n[::-1],(ord(n[-1])+ord(n[(n==n[::-1])*len(n)/2]))&1)

Try it online!

PowerShell, 114 99 bytes
param($n)((0,(($z=$n[0]%2)-eq$n[-1]%2)),(1,($z-eq$n[$n.length/2]%2)))[($n-eq-join$n[$n.length..0])]

Try it online!
Saved 15 bytes thanks to @Sinusoid.
Inputs as a string. Outputs an array of type (0|1) (True|False), with the 0 indicating "not a palindrome" and the 1 indicating "palindrome", and the True indicating parity matches and False otherwise.
This is done by using a pseudo-ternary and indexing into the appropriate place (a,b)[index]. The index ($n-eq-join$n[$n.length..0]) checks whether the input is a palindrome. If it is not, we take the a portion, which is a 0 coupled with whether the parity of the first digit $n[0] is -equal to the parity of the last digit $n[-1]. Otherwise, we're in the b portion, which is a 1 coupled with whether $z (the parity of the first digit) is -equal to the parity of the middle digit $n[$n.length/2].
Previously, I had "$($n[0])" to get the first digit to cast correctly as an integer, since $n[0] results in a char and the modulo operator % coalesces chars based on the ASCII value, not the literal value, whereas a string does the literal value. However, @Sinusoid helped me to see that 0,1,2,...,9 as literal values all have the same parity as 48,49,50,...,57, so if it uses the ASCII value we still get the same result.
That array is left on the pipeline, and output is implicit.

Out of curiosity, why did you have to use double quotes and an extra $ when you did modulus %2 to a number? I tried this myself and it wasn't necessary if I individually did each step, but it is when you put it inside an array? Does powershell treat it as a different variable type?

@Sinusoid It's taking input as a string, so when $n[0] indexes, it comes out as a char. The cast from char to int forced by the % operator doesn't go from '1' to 1, but to the ASCII value, so it's 49. The "$( )" does an explicit cast to string instead, which properly converts it to 1. ... Although, now that you mention it, the parity of 0..9 is the same as ASCII 48..57, so I can probably golf that down. Thanks!

@Sinusoid 15 bytes saved, thanks!

Java 8, 205 197 182 168 134 bytes
n->{int l=n.length(),a=n.charAt(0)%2;return n.equals(new StringBuffer(n).reverse()+"")?a==n.charAt(l/2)%2?4:3:a==n.charAt(l-1)%2?2:1;}

Outputs: 1 for false-false; 2 for false-true; 3 for true-false; 4 for true-true.
Explanation:
Try it here.
n->{                     // Method with String parameter and integer return-type
  int l=n.length(),      //  The length of the input String
      a=n.charAt(0)%2,   //  Mod-2 of the first digit
  return n.equals(new StringBuffer(n).reverse()+"")?
                         //  If the String is a palindrome
    a==n.charAt(l/2)%2?  //   And if the first and middle digits are both even/odd
     4                   //    return 4
    :                    //   Else
     3                   //    Return 3
   :a==n.charAt(l-1)%2 ? //  Else-if the first and last digits are both even/odd
    2                    //   Return 2
   :                     //  Else
    1;                   //   Return 1
}                        // End of method

Perl 6, 48 bytes
{($/=.flip==$_),[==] .ords[0,($/??*/2!!*-1)]X%2}

Try it
results in (True True) (True False) (False True) or (False False)
Expanded:
{                  # bare block lambda with implicit parameter ｢$_｣

  (
    $/ =           # store in ｢$/｣
    .flip == $_    # is ｢$_｣ equal backwards and forwards
  ),

  [==]             # reduce the following using &infix:<==> (are they equal)

    .ords\         # list of ordinals (short way to make ｢$_｣ indexable)
    [
      0,           # the first digit's ordinal
      (
        $/         # if the first test is True (palindrome)
        ??   * / 2 # get the value in the middle
        !!   * - 1 # else get the last value
      )
    ]
    X[%] 2         # cross those two values with 2 using the modulus operator
}

VBA, 117 99 bytes
Saved 18 bytes thanks to Titus
Sub p(s)
b=s
If s=StrReverse(s)Then r=2:b=Left(s,Len(s)/2+.1)
Debug.?r+(Left(s,1)-b And 1);
End Sub

It doesn't expand much once formatted:
Sub p(s)
    b = s
    If s = StrReverse(s) Then r = 2: b = Left(s, Len(s) / 2 + 0.1)
    Debug.Print r + (Left(s, 1) - b And 1);
End Sub

Here are the given test case results:
s = 12345678     p(s) = 1 = False False
s = 12345679     p(s) = 0 = False True
s = 12344321     p(s) = 3 = True False
s = 123454321    p(s) = 2 = True True

Does VBA have bitwise operators? Try &1 instead of mod 2. You might also get rid of the If/Then with r=r+2-2*(left(s,1)-b &1) or even better If s = StrReverse(s) then r=2 and r=r+1-(left(s,1)-b &1) ... and 2 bytes off with reversing the Tricky#2: r=r+(left(s,1)-b &1); save more with printing it directly: Debug.Print r+(left(s,1)-b &1). Should be 95 bytes then; 98 if &1 does not work.

@Titus Thanks! I wasn't familiar with bitwise operations at all, actually. VBA does have bitwise operations but they use And instead of just &. I figured out how to implement your first suggestion but I couldn't figure out how you meant to change the 3rd line with StrReverse.

Sub p(s);b=s;If s=StrReverse(s)Then r=2:b=Mid(s,Len(s)/2+.1,1);Debug.?r+(Left(s,1)-b&1);End Sub -> 0/2 for palindromes, 1/0 for Tricky#2

Oh and you should be able to replace the Mid() with Left(s,Len(s)/2+1) or so.

@Titus Ahh, OK. I kept trying to revise the portion that set b to a new value after the If statement. I need get more familiar with bitwise operations, I think...

Why +.1 and not +1?

@Titus Because VBA is stupid and doesn't always round up from 0.5. It uses round-to-even logic. If the string is 9 characters long, then Len(s)/2 = 4.5 which VBA will round to 4. If it's 7 characters long, then Len(s)/2 = 3.5 which VBA will also round to 4. Adding 0.1 corrects the lunacy.

Haskell, 89 bytes
(x:r)#y=mod(sum$fromEnum<$>[x,y])2
f x|reverse x/=x=2+x#last x|y<-length x`div`2=x#(x!!y)

Try it online! Usage: f "12345". Returns 0 for True True, 1for True False, 2 for False True and 3 for False False.
The function # converts both digit characters into their ascii character codes and sums them. If both are even or both are odd the sum will be even, otherwise if one is even and the other odd the sum will be odd. Calculating modulo two, # returns 0 for equal parity and 1 otherwise. f checks if the input string x is a palindrome. If not then # is called with x and the last character of x and two is added to the result, otherwise if x is palindromic call # with the middle character of x instead and leave the result as is.

Kotlin, 142 bytes
fun Char.e()=toInt()%2==0;
val y=x.reversed()==x;val z=x.first();println("${y},${if(y)z.e()==x.get(x.length/2).e();else z.e()==x.last().e()}")

Try it online!
fun Char.e() = toInt() % 2 == 0; //character extension function, returns if character(as int) is even

val y = x.reversed() == x
val z = x.first()

println(
"${y} //returns whether or not input is a palindrome
, //comma separator between the values
${if(y) z.e() == x.get(x.length/2).e() // if it's a palindrome compare first and middle parity
else z.e() == x.last().e()}" //else compare first and last parity
)

CJam, 32 bytes
q:N_W%=N0=~2%NW=~2%N_,2/=~2%3$?=

Input is a number on top of the stack.
Explanation:
q                                 e# Read input:          | "12345679"
 :N                               e# Store in N:          | "12345679"
   _                              e# Duplicate:           | "12345679" "12345679"
    W%                            e# Reverse:             | "12345679" "97654321"
      =                           e# Check equality:      | 0
       N                          e# Push N:              | 0 "12345679"
        0=~                       e# First digit:         | 0 1
           2%                     e# Modulo 2:            | 0 1
             N                    e# Push N:              | 0 1 "12345679"
              W=~                 e# Get last digit:      | 0 1 9
                 2%               e# Modulo 2:            | 0 1 1
                   N              e# Push N:              | 0 1 1 "12345679"
                    _             e# Duplicate:           | 0 1 1 "12345679" "12345679"
                     ,            e# Length:              | 0 1 1 "12345679" 8
                      2/          e# Divide by 2:         | 0 1 1 "12345679" 4
                        =         e# Get digit (as char): | 0 1 1 '5
                         ~        e# Eval character       | 0 1 1 5
                          2%      e# Modulo 2:            | 0 1 1 1
                            3$    e# Copy stack element:  | 0 1 1 1 0
                              ?   e# Ternary operator:    | 0 1 1
                               =  e# Check equality:      | 0 1

REXX, 104 100 bytes
arg a
parse var a b 2''-1 c
e=a=reverse(a)
b=b//2
if e then f=b&centre(a,1)//2
else f=b&c//2
say e f

Returns logical value pair 0 0, 0 1, 1 0 or 1 1.

R, 115 109 105 bytes
w=strtoi(el(strsplit(scan(,""),"")))
c(p<-all(w==rev(w)),w[1]%%2==switch(p+1,tail(w,1),w[sum(1|w)/2])%%2)

Takes input from stdin. Returns FALSE FALSE for False False, FALSE TRUE for False True, TRUE FALSE for True False, and TRUE TRUE for True True.

AWK, 97 96 bytes
{n=split($0,a,"")
for(;j<n/2;)s+=a[j+1]!=a[n-j++]
x=(a[1]%2==a[s?n:int(n/2)+1]%2)+(s?0:2)
$0=x}1

Simplest usage is to place the code into file: OddEven then do:
awk -f OddEven <<< "some number here"

Output is essentially the bit-sum of the comparisons in the Question, e.g.
0, Not palindrome and first and last digits have different parity
1, Not palindrome and first and last digits have same parity
2, Palindrome and the first digit and middle digit have different parity
3, Palindrome and the first digit and middle digit have same parity

I tried removing the () from (s?0:2) but this messes up operator precedence somehow.

Saved a byte by moving the increment on j. This means the for() could be replaced with a while(), but no bytes would be saved in doing so :(

Ruby, 60 + 1 = 61 bytes
Uses the -n flag.
r=->i{$_[i].to_i%2}
p e=$_.reverse==$_,r[0]==r[e ?~/$//2:-1]

Try it online!

Groovy, 326 303 bytes
Shrunk Code:
String str="12345678";char pal,par;pal=str==str.reverse()?'P':'N';if(pal=='P'){par=(int)str.charAt(0).toString()%2==str.charAt((int)str.length()-1-(int)((str.length()-1)/2))%2?'S':'N'}else{par = (int)str.charAt(0).toString()%2==str.charAt((int)(str.length()-1)%2)?'S':'N'};print((String)pal+(String)par)

Original Code (with Explanation):
Declare str as String                        String str = "12345678"
Declare pal and par as char                  char pal, par
Check if Palindrome or not                   pal = str==str.reverse()?'P':'N'
If Palindrome...                             if (pal=='P') {
and has same parity (S) and if not (N)       par = (int)str.charAt(0).toString()%2==str.charAt((int)str.length()-1-(int)((str.length()-1)/2))%2?'S':'N'
else if not palindrome...                    } else {
and has same parity (S) and if not (N)       par = (int)str.charAt(0).toString()%2==str.charAt((int)(str.length()-1)%2)?'S':'N'
closing tag for if                           }
Print desired output                         print((String)pal+(String)par)

Original Code (without Explanation):
String str = "12345678"
char pal, par
pal = str==str.reverse()?'P':'N'
if (pal=='P') {
    par = (int)str.charAt(0).toString()%2==str.charAt((int)str.length()-1-(int)((str.length()-1)/2))%2?'S':'N'
} else {
    par = (int)str.charAt(0).toString()%2==str.charAt((int)(str.length()-1)%2)?'S':'N'
}
print((String)pal+(String)par)

Input:
Just change "12345678" to another set of non-negative digits.

Output:
"PS" - Palindrome with Same Parity
"PN" - Palindrome with Diff Parity
"NS" - Non-palindrome with Same Parity
"NN" - Non-palindrome with Diff Parity

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
You had me at hello
Task
Read in a possibly infinite text stream or file, outputting its contents until the word hello has been output, abiding to the following rules.

Once hello has been output, your code should quit immediately. It should not wait for a newline for example.
Your code should output as it goes. That is it shouldn't read in a huge amount of input and then start outputting.
If the stream/file doesn't contain hello, your code should just carry on outputting the input forever or until the end of the stream/file is reached.
This is a case sensitive challenge, so hello is not equal to Hello.
You may assume that the input consists solely of printable ASCII characters and newlines.
Your code can't expect that the text will be terminated by a newline or that there will be any newlines at all in the input. Also, you code cannot assume that it will run on a machine with an infinite amount of memory.
You may assume that your code will be called from an empty directory.

Example input stream
I once had a horse called hellopina.

Output
I once had a horse called hello

Tip
Run yes | tr -d \\n | <your program> to check if it works with
infinite streams. If it doesn't print anything and/or leaks memory,
the program doesn't comply with the spec. It should print yyyyyyyyyyyyyyyyyyyyyy... forever with no newlines.

Are we permitted to read anything after the "hello"?  The question seems to prohibit any additional read, which could be problematic in languages such as (Standard) C, that provide buffered input with automatic read-ahead.

You should probably change teh accepted answer to the assembly one, as it's 2 byte shorter.

@Riker It would be great if someone could test it or at least say they believe it works first.

Jelly, 24 bytes
“Ṣẉ»ẇ⁸Ṇȧ®
ṫ-3;ƈ©Ȯ¤µ⁺Ç¿ṛ“

Try it online!
Explanation:
ṫ-3;ƈ©Ȯ¤µ⁺Ç¿ṛ“ Main link. Arguments: 0
ṫ-3            Truncate the list to its 4 last elements.
   ;ƈ©Ȯ¤       Store a character from STDIN in the register, print it, and append it to the list (list is initially [0]).
        µ      Start a new monadic chain, everything to the left is a link.
          Ç    Execute the helper link with the existing list as its argument.
         ⁺ ¿   Do-while loop, left link is body, right link is condition.
            ṛ“ When the loop ends, replace the return value with [] (invisible on output).

“Ṣẉ»ẇ⁸Ṇȧ® Helper link. Arguments: string
“Ṣẉ»ẉ⁸Ṇ   Check if "hello" isn't in the string.
        ® Return the character we stored in the register.
       ȧ  Check if both of the above are truthy.

C (gcc), 81 80 76 75 72 71 70 69 bytes
main(n,c){while(~(c=getchar())&n-0xb33def<<7)n=n<<5^putchar(c)/96*c;}

Try it online!
How it works
This is a full program. We define a function f for our purposes. To save bytes, it is declared with two argument that default to int. This is undefined behavior, but in practice, n will be initialized as 1 when running the program without additional arguments, c will hold the lower 32 bits of the pointer to the argument vector
While the condition
~(c=getchar())&n-0xb33def<<7

holds, we'll execute the while loop's body:
n=n<<5^putchar(c)/96*c

To fully understand the condition, we must first examine the body. For now, all we observe is that c=getchar() reads a single byte from STDIN (if possible) and stores it in the variable c.
The byte sequence hello looks as follows in different representations.
char     decimal     binary (8 bits)
'h'      104         0 1 1 0 1 0 0 0
'e'      101         0 1 1 0 0 1 0 1
'l'      108         0 1 1 0 1 1 0 0
'l'      108         0 1 1 0 1 1 0 0
'o'      111         0 1 1 0 1 1 1 1

All of these fall in the range [96, 192), so c/96 will evaluate to 1 for each of these bytes, and to 0 for all remaining ASCII characters. This way, putchar(c)/96*c (putchar prints and returns its argument) will evaluate to c if c is `, a lowercase letter, one of {|}~, or the DEL character; for all other ASCII characters, it will evaluate to 0.
n is updated by shifting it five bits to the left, then XORing the result with the result from the previous paragraph. Since an int is 32 bits wide (or so we assume in this answer), some of the shifted bits might "fall off the left" (signed integer overflow is undefined behavior, but gcc behaves as the x64 instruction it generates here). Starting with an unknown value of n, after updating it for all characters of hello, we get the following result.
 n  ?????????????????????????|???????
'h'                          |    01101000
'e'                          |         01100101
'l'                          |              01101100
'l'                          |                   01101100
'o'                          |                        01101111
-----------------------------+--------------------------------
    <------ discarded ------>|???????0101100110011110111101111

Note that the lower 25 bits form the integer 0xb33def, which is the magic constant in the condition. While there is some overlap between the bits of two adjacent bytes, mapping bytes below 96 to 0 makes sure that there aren't any false positives.
The condition consists of two parts:

~(getchar()) takes the bitwise NOT of the result of reading (or attempting to read) a byte from STDIN.
If getchar succeeds, it will return the value of the read byte as an int. Since the input consists entirely of ASCII characters, the read byte can only have its lower 7 bits set, so the bitwise NOT will have its highest 25 bits set in this case.
If getchar fails (no more input), it will return -1 and the bitwise NOT will be 0.
n-0xb33def<<7 subtracts the magic constant from before from n, then shifts the result 7 units to the left.
If the last 5 read bytes were hello, the lowest 25 bits of n will be equal to 0xb33def and the subtraction will zero them out. Shifting the difference will yield 0 as the 7 highest bits will "fall off the left".
On the other hand, if the last 5 read bytes were not hello, one of the lowest 25 bits of the difference will be set; after shifting, one of the highest 25 bits will be.

Finally, if getchar was successful and we didn't print hello yet, the bitwise AND, all of the highest 25 bits of the left operand and at least one of the highest 25 bits of the right one will be set. This way, & will yield a non-zero integer and the loop continues.
On the other hand, if the input is exhausted or we have printed hello already, one of the bitwise AND's operand will be zero, and so will the result. In this case, we break out of the loop and the program terminates.

You probably ought to mention that this depends on the input being encoded in ASCII, before delving into the explanation.

@TobySpeight I don't think it's common to specify this. What kind of ASCII incompatible encoding would you expect a C answer to use?

EBCDIC is the obvious encoding that's not ASCII.  C doesn't prescribe any particular character encoding (only that the decimal digits must be represented by consecutive values, in order).

the above program stop if the stream contain the not ascii string "«úá÷o" 1: o 111 6f 2: ÷ 246 f6 3: á 160 a0 4: ú 163 5: « 174

@RosLuP The challenge spec guarantees that the input will consist of printable ASCII characters and newlines.

Bash, 74 75 103 99 88 82 76 bytes
-10 bytes thanks to @DigitalTrauma!
-11 bytes thanks to @manatwork!
-6 bytes thanks to @Dennis!
IFS=
b=ppcg
while [ ${b/hello} ];do
read -rN1 a
b=${b: -4}$a
echo -n $a
done

Explanation:
IFS=    # making sure we can read whitespace properly
b=ppcg  # set the variable b to some arbitrary 4 letter string

while [ ${b/hello} ]; do  # while the variable b doesn't contain "hello", do the following
    read -rN1 a           # get input
    b=${b: -4}$a          # set b to its last 4 chars + the inputted char
    echo -n $a            # output the inputted char
done

Try it online!

This is great! I was hoping there would be a bash answer.

Labyrinth, 43 41 bytes
Thanks to Sp3000 for saving 2 bytes.
<_%-742302873844_::%*:*:420#+.:%):,*652_>

Try it online!
Explanation
The basic idea is to encode the last five characters in base 256 in a single integer. When a new character comes in, we can "append" it by multiplying the integer by 256 and adding the new code point. If we want to look only at the last 5 characters, we take the value modulo 2565 = 240 = 1099511627776. Then we can simply check whether this value is equal to 448378203247, which is what we get when we treat the code points of hello as base-256 digits.
As for the code... <...> is a bit of a Labyrinth idiom. It allows you to write an infinite loop without any conditional control flow on a single line, saving a lot of bytes on spaces and linefeeds. The main condition for this to work is that there are two disposable values on top of the stack when we reach the < (we normally use 0s for that, but the actual value is arbitrary).
Of course, the program does need some conditional logic to figure out when to terminate. But conditionally ending the program is possible by dividing by a value which is zero when we want the program to end. The <...> construct works by shifting the entire row left (cyclically) when the IP is at the left end, and then immediately shifting it back into position. This means that the code is actually executed right to left. Let's reverse it:
_256*,:)%:.+#024:*:*%::_448378203247-%_

This is one iteration of the loop which reads a character, terminates if we've reached EOF, prints the character, adds it to our encoding, truncates that to 5 characters, checks for equality with hello and repeats. Here is how that works in detail (remember that Labyrinth is stack-based):
_256*            Multiply the encoding by 256 in preparation for the next iteration.
,                Read one byte from STDIN.
:)%              Duplicate, increment, modulo. If we hit EOF, then , returns
                 -1, so incrementing and modulo terminates the program due to
                 the attempted division by zero. However, if we did read a
                 character, we've just compute n % (n+1), which is always n itself.
:.               Print a copy of the character we just read.
+                Add it to our encoding (we'll make sure to multiply the
                 encoding by 256 at the end of the iteration, so there's room
                 for our new character).
#024             Push 1024, using the stack depth to push the initial 1.
:*:*             Square it twice. That gives 2^40.
%                Take the encoding modulo 2^40 to truncate it to the last 5
                 characters.
::               Make two copies of the encoding.
_448378203247    Push the value that corresponds to "hello".
-                Subtract it from the encoding, giving zero iff the last 5
                 characters were "hello".
%                Take the other copy of the encoding modulo this value, again
                 terminating if we've reached "hello".
                 The actual value of this modulo - if it didn't terminate the
                 the program - is junk, but we don't really care, we just need
                 any disposable value here for the <...>
_                We push a zero as the second disposable value.

Bash, 73 68 66 bytes
IFS=
[[ $1 != olleh ]]&&read -rN1 c&&echo -n $c&&exec $0 $c${1::4}

Assumes a directory with no or only hidden files. Must be run as <path/to/script>.
Try it online!
How it works (outdated)
At the beginning of the while loop, we first test if the string in the variable s (initially empty) equals olleh (hello backwards, olé), and return 0 (match) or 1 (not a match) accordingly. While formally part of the loop's condition, the outcome won't affect it on its own, as only the last command before do determines if the condition holds.
Next, we set the internal field separator to the empty string (so read won't choke on whitespace), read raw bytes (-r) from STDIN and store them in c. $? is the exit code of the previous command, so this reads exactly one (-N1) byte for a non-match and zero bytes (-N0). Reading zero bytes, whether its due to hitting EOF or because -N0 was specified, causes read to exit with status code 1, so the while loop will end; otherwise, the body is executed and we start over.
In the body, we first print the byte we read, then update s with s=$c${s::4}. This prepends the read byte to (up to) the first four bytes in s, so s will equal olleh once hello has been printed.

Very nice indeed!

brainfuck, 117 bytes
--->>>------>>>+>>>+>>>++++<,[.-----<-[>--<-----]<[<<<]>>>[<[<<<+>>>>->+<<-]>[>>
+>]<[+[-<<<]]>>[<+>-]>>]<[[-]<<<,<]>]

Formatted:
--->>>------>>>+>>>+>>>++++
<,
[
  .-----<-[>--<-----]<[<<<]
  >>>
  [
    <[<<<+>>> >->+<<-]
    >[>>+>]
    <[+[-<<<]]
    >>[<+>-]
    >>
  ]
  <[[-]<<<,<]
  >
]

Try it online.
This initializes the tape with the characters in hello offset by 107, spaced out with one value every three cells, then keeps track of the last five characters seen and checks for a match with every new character processed, using a flag to the right of the string to keep track of whether there has been a match.

Brainfuck, 658 bytes
+[>,.>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[-<->]+<[>-<[-]]>[-<,.>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[-<->]+<[>-<[-]]>[-<,.>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[-<->]+<[>-<[-]]>[-<,.>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[-<->]+<[>-<[-]]>[-<,.>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[-<->]+<[>-<[-]]>[-<<->>]]]]]<<]

Over 500 bytes are in the constants which I need to golf a bit.
It essentially is a state machine, so infinite input is not a problem.
This is the slightly commented version
+
[
  >,.
  >h
  [-<->]
  +<
  [
    >-<[-][in input spot, not h]
  ]
  >
  [
    -
    <
    [in input spot, h has been read]
    ,.
    >e
    [-<->]
    +<
    [
      >-<[-][in input spot, not e]
    ]
    >
    [
      -
      <
      [in input spot, e has been read]
      ,.
      >l
      [-<->]
      +<
      [
        >-<[-][in input spot, not l]
      ]
      >
      [
        -
        <
        [in input spot, l has been read]
        ,.
        >l
        [-<->]
        +<
        [
          >-<[-][in input spot, not l]
        ]
        >
        [
          -
          <
          [in input spot, l has been read]
          ,.
          >o
          [-<->]
          +<
          [
            >-<[-][in input spot, not o]
          ]
          >
          [
            -
            <
            [in input spot, o has been read]
            <->>
          ]
        ]
      ]
    ]
  ]
  <<
]

This looks fun :)

Welcome to Programming Puzzles and Code Golf StackExchange!

This code has multiple issues, but the biggest issue is that it doesn't include logic to handle cases like ahehellob properly; in the middle of a potential match, it only checks for the next letter in hello and doesn't look for an h to start over.

Ruby, 46 60 bytes
a="";loop{q=$<.getc;~p if a[-5..-1]=="hello"||!q;a+=q;$><<q}

Try it online!
Reads characters from stdin until the last 5 are hello, then outputs the string (or until no characters are left in stdin). Terminates with error.
Equivalent to:
a = ""
loop {
    q = $<.getc
    ~p if a[-5..-1] == "hello" || !q
    a += q
    $><< q
}

Or, more ungolfed:
a = ""
loop do
    q = STDIN.getc
    break if a[-5..-1] == "hello" or not q
    a += q
    print q
end

a grows everytime a char is read. Does this crash if the input is infinite?

@betseg hm, maybe. Let me see if I can fix that

Python 3, 120 116 104 Bytes
Works with infinite streams, first time golfing, any tips are appreciated.
import sys
a=1
c=''
while(a):
    a=sys.stdin.read(1)
    if a:print(end=a)
    c=(c+a)[-5:]
    if c=='hello':break

Thanks @DJMcMayhem for saving some bytes :)

Welcome to the site! c=[0,c+1]['hello'[c]==a] should save you some bytes. Also, a=1 is shorter too.

You don't need the parenthesis for while in Python.

Cubix, 94 83 82 79 63 56 bytes
p>q'-?w.uh'e@U7.'hqi?oqB-!ul.-..$WWu_q<o'\;>....6t?.../!@

Expanded:
        p > q '
        - ? w .
        u h ' e
        @ U 7 .
' h q i ? o q B - ! u l . - . .
$ W W u _ q < o ' \ ; > . . . .
6 t ? . . . / ! @ . . . . . . .
. . . . . . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

Notes

The interpreter disables the input field when the program starts. As such, an infinite stream of input is impossible. This program takes the input character-by-character, so if it weren't for this limitation, it would work properly.
This program doesn't clear up the stack, and it gets messy very quickly. Since the machine this will be used on apparently can give infinite input streams, it seems reasonable to assume that it also has infinite memory.
Any and all golfing help is much appreciated.

Try it online
You can try the program here.
Explanation
General idea
The general idea is that we want to read a character, and then check it against varying characters (first h, then e, then l etc.). To keep track of the character we have missed, we keep it at the very bottom of the stack. When we need it, we can easily bring it to the top again.
Read/Write loop
The read-write loop is simply the 5th line. All characters that are not used are replaced by no-ops (.):
        . . . .
        . . . .
        . . . .
        @ . . .
' h q i ? o q B - ! u l . - . .
. . . . _ . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

This can be split up in two parts: Reading and (writing and checking). The first part contains the instructions up to and including the question mark. The second part up is the rest of the line. Because this loops around, we assume we start with a stack of [...]
    @
'hqi?
    _

Explanation
'h          Push the character code of the h
            Stack: [..., 104]
  q         Send it to the bottom
            Stack: [104, ...]
   i        Read one character of the input (-1 for EOF)
            Stack: [104, ..., input]
    ?       Start of condition:
              if (input < 0):
    @           execute '@', ending the program
              if (input = 0):
                continue going right
              if (input > 0):
    _           turn to the right, reflect back ('_') and
                turn right again, effectively not changing
                the direction at all

The second part (writing and checking) is linear again. The stack starts as [next-char, ..., input]. We abstracted the next character, because that changes later in the program.
oqB-!ul.-  Explanation
o          Output the character at the top of the stack
 q         Send the input to the bottom of the stack
           Stack: [input, next-char, ...]
  B        Reverse the stack
           Stack: [..., next-char, input]
   -       Push the difference of the top two characters, which
           is 0 if both are equal, something else otherwise
           Stack: [..., next-char, input, diff]
    !      if (diff = 0):
     u       make a u-turn to the right
           else:
      l.     execute two no-ops
        -    push [input - next-char - input], which is disregarded
             later, so it effectively is a no-op as well.

Now, the IP will start again at the beginning of this loop, resetting the next character to check to h.
Matching the next character
If the IP made a u-turn (i.e. the character we read and printed matched the next character in 'hello'), we need to check what character the input was and depending on that, push the next character to the bottom of the stack. After that, we need to return to the read/write loop, without pushing h to the stack, so we need another way to get there.
First things first: determine what character the input was. The stack looks like this: [..., prev-char, input, 0].
        . . . .
        - ? . .
        u h ' e
        . . . .
. . . . . . . . . ! u . . . . .
. . . . . . . . . \ ; . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

To compare the input, we use the character code of h again. Initially, this was because I didn't really know how I was going to handle this and h is the first character in the string to check for, but it ended up being quite convenient. If we subtract the character code of h from the input, we get -3 if the input is e, 0 if the input is h, 4 if the input is l and 7 if the input is o.
This is useful, because the ? command lets us easily separate negative values from positive values and zero. As such, if the IP turns left, the difference was negative, so the input was e, so the next character should be an l. If the IP continues going straight, the difference was 0, so the input was h, so the next character should be an e. If the input is an l or an o, the IP turns right.
All instructions executed before the aforementioned question mark are:
;!e'h-     Explanation
;          Delete the top of the stack
           Stack: [..., prev-char, input]
 !         if (input = 0):
  e          execute 'e' (no-op)
   'h      Push the character code of h
           Stack: [..., prev-char, input, 104]
     -     Push the difference of the input and 104
           Stack: [..., prev-char, input, 104, diff]

Now the IP changes its direction as detailed above. Let's go over the different possibilities.
Input 'e'
First we'll consider the input e, which causes the IP to move upwards from the ?, since the difference is 3. All irrelevant characters have been removed from the cube.
        . > q '
        . ? . .
        . . . .
        . . . .
. . q . . . . . . . . l . . . .
$ W W . . . . . . . . > . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

The characters are executed in this order (excluding some control-flow characters):
q'l$WWq
q           Save the difference (-3) to the bottom of the stack so
            we can tell whether the l on the bottom of the stack is
            the first or the second l in hello
            Stack: [-3, ...]
 'l         Push the character code of l to the stack
            Stack: [-3, ..., 108]
   $W       no-op
     W      Sidestep into the loop
      q     Send the character code to the bottom
            Stack: [108, -3, ...]

Now the IP has reached the read/write loop again.
Input 'h'
If the input was 'h', the difference is 0, so the IP doesn't change its direction. Here's the cube again, with all irrelevant characters removed. Since this path includes quite a few no-ops, all the no-ops it passes have been replaced by &. The IP starts at the question mark.
        . . . .
        . ? w .
        . . ' e
        . . . .
. . . . . . . . . ! . . . . . .
. . . u _ q < . . \ . . . . . .
. . ? & & & / . . & . . . . . .
. . & . . . . . . & . . . . . .
        . . . .
        & & & &
        . . . .
        . . . .

The instructions executed are:
'e!\?q_
'e          Push the character code of the e
            Stack: [..., 101]
  !         if (101 = 0):
   \          reflect away (effectively a no-op)
    ?       if (101 > 0):
              turn right (always happens)
     q      Move 101 to the bottom of the stack
            Stack: [101, ...]
      _     No-op

And now we're entering the read/write loop again, so we're done.
Other inputs
All other inputs result in a positive difference, so the IP turns right at the question mark. We still need to separate the l and the o, so that's what we'll do next.
Separating the 'l' and 'o'
Keep in mind that the difference is 7 for o and 4 for l and that we have to end the program if the input was an o. Here's the cube again with the irrelevant parts replaced by a . and the no-ops the IP crosses have been replaced by ampersands.
        . . q .
        . ? w .
        . h ' .
        . U 7 .
. . . . . . . . . . . . . - . .
. . . . . . . . . . . . . & . .
. . . . . . / ! @ . . . . & . .
. . . . . . & . . . . . . & . .
        . . & .
        . . & .
        . . & .
        . . & .

h7'wq-!@
h           no-op
 7          Push 7 to the stack
            Stack: [..., diff, 7]
  'wq       Push w to the stack and send it to
            the bottom. We don't care about it,
            so it's now part of the ellipsis.
            Stack: [..., diff, 7]
     -!     if (diff = 7):
       @        End the program

Discerning between the two 'l's
So, now we've we know that the input was an l, but we don't know which l. If it's the first, we need to push another l to the bottom of the stack, but if it's the second, we need to push an o. Remember we saved -3 to the bottom of the stack just before we pushed the first l? We can use that to separate the two branches.
        . . . .
        . . . .
        . . . .
        . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
6 t ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

The stack starts as [..., -3 or 140, ...]
Explanation
6t?
6t          Take the 6th item from the top and move
            it to the top (which is either -3 or 140)
  ?         If that's positive, turn right, otherwise,
            turn left

First 'l'
If this was the first 'l', we need to push another 'l'. To save bytes, we use the same characters as for the first 'l'. We can simplify the stack to [...]. Here's the relevant part of the cube, with no-ops replaced by ampersands.
        p > q '
        . . . .
        . . . .
        . . . .
' . q . . . . . . . . l . . . .
$ W W . . . . . . . . > & & & &
. . ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

The following instructions are executed:
$'pq'lq
$'          no-op
  pq        no-op
    'l      Push the character code of l
            Stack: [..., 108]
      q     Send it to the bottom
            Stack: [108, ...]

We're about to enter the read/write loop, so we're done with this branch.
Second 'l'
If the input was the second 'l' in 'hello', the IP turned right at the question mark. Once again, we can simplify the stack to [...] and the IP starts at ?, pointing south this time.
        . . . .
        . . . .
        . . . .
        . . . .
. . . . . . . . . . . . . . . .
. . . u _ q < o ' \ . . . . . .
. . ? . . . . . . & . . . . . .
. . & . . . . . . & . . . . . .
        . . . .
        & & & &
        . . . .
        . . . .

The instructions executed are:
'oq_
'o          Push the character code of 'o'
            Stack: [..., 111]
  q         Move the top item to the bottom
            Stack: [111, ...]
   _        No-op

And the IP is about to enter the read/write loop again, so we're done with this branch as well.

An heroic effort!

Haskell, 41 47 43 bytes
f l|w@"hello"<-take 5l=w|a:b<-l=a:f b|1<2=l

Haskell's laziness handles the infinite input/output quit well.
Try it online!
Edit: didn't handle finite input - fixed. Thanks @Leo for pointing out.
Edit II: @Ørjan Johansen saved 4 bytes. Thanks!

The input may also be finite, so I think you need to deal with the case when you reach the end of the string

@Leo: Oops, totally missed it. Fixed.

The first guard can be shortened to |w@"hello"<-take 5l=w.

@ØrjanJohansen: oh, that's a nice one. Thanks!

C++, 142 141 bytes
#import<iostream>
void f(std::istream&i){i>>std::noskipws;char c;for(std::string s="     ";s!="hello"&&i>>c;)s.erase(0,1),s+=c,std::cout<<c;}

Try it online!

Would this be possible with GCC? I don't see #import in GCC C++ programs...

@ckjbgames #import is a deprecated GCC extension.

@ckjbgames more info here: http://stackoverflow.com/questions/172262/c-include-and-import-difference

@iFreilicht That question actually made me ask that.

@ckjbgames you might want to take a look at the second answer: http://stackoverflow.com/a/172264/2533467
"The import in gcc is different from the import in VC++. It is a simple way to include a header at most once only."

Node, 124 bytes
with(process)with(stdin)on('data',d=>[...d].map(c=>(s=(stdout.write(c),s+c).slice(-5))=='hello'&&exit()),setEncoding(),s='')

Not assuming that the stream will fit in available memory.

PHP, 57 55 53 bytes
while(hello!=$s=substr($s.$c,-5))echo$c=fgetc(STDIN);

as there are no infinite files, I take input from STDIN. Run with -nr.
Loop through input, print the current character, append it to $s, cut $s to the last 5 characters. Break loop when $s is hello.

C#, 134 bytes
using C=System.Console;class P{static void Main(){var s="";for(int c;(c=C.Read())>=0&!s.Contains("olleh");C.Write(s[0]))s=(char)c+s;}}

Try It Online
Reads a character, checks it isn't -1 (EOS) and that we havn't seen "hello" yet, then prepends it to a string, and writes the character out. We prepend because s[0] is a lot shorter than (char)s. This has a quadratic cost in the length of the string, as it has to allocate and scan the entire input each time it reads a character (this will crash after 2GB of input due to constraints in the CLR, is that allowed?)
using C=System.Console;

class P
{
    static void Main()
    {
        var s="";
        for(int c;(c=C.Read())>=0&!s.Contains("olleh");C.Write(s[0]))
            s=(char)c+s;
    }
}

For a (longer: 142 bytes) version which won't run out of memory, and which has constant per-character cost, see below:
using C=System.Console;class P{static void Main(){var s="     ";for(int c;(c=C.Read())>=0&s!="hello";C.Write(s[4]))s=s.Substring(1)+(char)c;}}

This one keeps the last 5 characters in a 5-length string, which means short comparisons, and cheap last-char lookup, but is considerably more expensive to update.
using C=System.Console;

class P
{
    static void Main()
    {
        var s="     ";
        for(int c;(c=C.Read())>=0&s!="hello";C.Write(s[4]))
            s=s.Substring(1)+(char)c;
    }
}

Vim, 39 bytes
:im hello hello:se noma
:map : i

i

Try it online!
:im hello                        "Remap 'hello' in insert mode to
          hello                "write hello, then hit escape
                 :se noma       "then set the buffer to not-modifiable
:map : i                        "THEN remap ':' to 'i' so that can't be changed

i                                "enter insert mode and await an infinite stream of input

Is this an accepted input method for Vim? I thought Vim programs usually expect the input to be already in the buffer before they start.

To be honest I don't know?  That's true, but hardly allows for an infinite stream, so I just did it this way without really thinking that hard about it.

What happens if there is an escape character in the input stream?

@dim I asked, and OP specified only printable ASCII and newlines.  ESC is not included in printable ASCII afaik

Ruby, 59 49 48 43 bytes
Now rant-free, shorter, and without memory leak.
s=''
s=$>.putc$<.getc+s[0,4]until'olleh'==s

Saved 5 bytes by getting rid of some parentheses and a space thanks to Dennis

Let us continue this discussion in chat.

PowerShell, 111 bytes
There is probably a better way to do this, but I can't see it at the moment.
while(($x=($x+$host.UI.RawUI.ReadKey("IncludeKeyDown").character+"     ").substring(1,5)).CompareTo("hello")){}

This reads the key strokes without supressing the echo.  The character is added to $x which is trimmed to the last 5 characters and compared to "hello".  This carries on until the comparison is true.
Note: this does not work in the PowerShell ISE.  ReadKey is disabled in that environment.

Python 3 (Linux), 73 72 bytes
s=c='_';I=open(0)
while'olleh'!=s>''<c:c=I.read(1);s=c+s[print(end=c):4]

Thanks to @MitchSchwartz for golfing off 1 byte!
Try it online!

I don't understand. How does the condition for while evaluate properly? It looks like you're comparing a boolean to an empty string.

s[print(end=c):4] saves a byte

@iFreilicht Python parses chained conditionals as one would in math (a<b<c, for example). The condition is a shorthand for 'olleh'!=s and s>''and''<c). The middle test isn't needed, but chaining them is shorter than the straightforward 'olleh'!=s and''<c.

@MitchSchwartz That it does. Thank you!

Scheme 115 bytes
(do((c(read-char)(read-char))(i 0(if(eqv? c(string-ref"hello"i))(+ i 1)0)))((or(eof-object? c)(= i 5)))(display c))

Readable version:
(do ((c (read-char) (read-char))                            ; read stdin
     (i 0 (if (eqv? c (string-ref "hello" i)) (+ i 1) 0)))  ; check target
    ((or (eof-object? c) (= i 5))) ; finish if end of stdin, or word found
  (display c))                     ; display each character

This takes an individual char from stdin each time around the loop, and marks off its position on the target word as it meets the characters of "hello".
Stops when the input runs out or "hello" has been seen.
No memory used on infinite stream.

Cool answer, welcome to the site!

AWK, 95 bytes
BEGIN{RS="(.)"
split("hello",h,"")}{for(j=0;++j<6;){c=RT
printf c
if(c!=h[j])next
getline}exit}

There are 2 things I learned here:
 1) To split records between characters use RS="(.)" and then RT must be used instead of $1
 2) ORS is used by print and is defaulted to "\n"
 3) I can't count to 2 and using printf is "cheaper" than assigning ORS and using print
Example usage:
Place code in FILE
awk -f FILE some_data_file

or
some process | awk -f FILE

Code was tested using Dennis's yes | ... suggestion and I saw lots and lots of ys.
FYI, you can do the RS assignment as an option and pull it out of the BEGIN block via:
awk -v RS='(.)'

Really tricky solution! (Maybe because it's Friday afternoon, but I find it good entry for obfuscated challenge too.) Though I would try a more awkish approach: BEGIN{RS="(.)"}{printf RT}"olleh"==a=RT substr(a,1,4){exit}.

Oddly enough I have almost exactly answer ready to submit an hour ago... and forgot to submit it. :p

8086 machine code, 22 bytes
00000000  bf 11 01 b4 01 cd 21 ae  75 f6 81 ff 16 01 72 f3  |......!.u.....r.|
00000010  c3 68 65 6c 6c 6f                                 |.hello|
00000016

Equivalent assembly code:
org 0x100
use16
a:  mov di, msg
b:  mov ah, 1       ; read one byte from stdin with echo
    int 0x21        ; dos syscall -> result in AL
    scasb           ; if (DI++ == AL)
    jne a
    cmp di, msg+5
    jb b
    ret
msg db "hello"

How does it work?

I added the equivalent assembly code. It basically relies on one very useful DOS syscall, which reads one byte from stdin and echos it back to stdout at the same time. The 8086 also has a single-byte string comparison instruction which comes in handy here.

Pyth, 49 47 bytes
Wn"hello"=>5+kp$__import__("sys").stdin.read(1)

Pyth's not very good at taking a single character of input. Everything in $__import__("sys").stdin.read(1) is simply doing that. Also, it means that this only runs offline.
Everything else is short...
The program is a bodyless while loop. Inside the condition, the program reads a character, prints it back, appends that character to k (which is initially the empty string), trims off all but the last 5 characters of k, and then checks that the result is not "hello".
32 characters are getting one byte of input, 15 characters does the rest.
Tested on Linux, works even with no newline, infinite input, etc.

Lua, 68 64 bytes
l=""while l~="hello"do c=io.read(1)io.write(c)l=l:sub(-4)..c end

Change the slicing to l:sub(-4), then you can reduce the initialization of l="".

@manatwork That's neat. Thanks for the tip.

Röda, 49 47 bytes
{a=[0]*5{|x|[x];a=a[1:]+x;z if[a&""="hello"]}_}

Try it online!
This is an anonymous function that reads characters from its input stream and outputs them until "hello" is found. It uses the array a to track the last characters.
It outputs some junk to STDERR, but I understood that is allowed.
Explanation:
{
    a=[0]*5                /* Initialize the array with 5 zeroes. */
    {|x|                   /* For each x in the input stream: */
        [x];               /* Print x */
        a=a[1:]+x;         /* Add x and remove the sixth last character. */
        z if[a&""="hello"] /* If "hello" is found, crash the program */
                           /* with an undefined variable. */
    }_                     /* End for loop. */
}

Where is the Roda documentation?

@ckjbgames Here. I use the latest version 0.12, which is in its own branch in Github.

Python + msvcrt (Windows), 114 105 bytes
Both of these solutions use information provided by this SO answer.
import sys,msvcrt
x=""
o=sys.stdout
while"hello"!=x[-5:]:c=msvcrt.getch();o.write(c);o.flush();x=x[-4:]+c

Python (Unix terminal), 145 136 135 bytes
Same as above, but for Unix terminal. This version can be partially tested online if you comment out the second line (to avoid an error), except that the input has to be user-entered and newline terminated (only to test online). For the full functionality, you have to run in a terminal.
import sys as s,tty
tty.setraw(s.stdin.fileno())
x=""
o=s.stdout
while"hello"!=x[-5:]:c=s.stdin.read(1);o.write(c);o.flush();x=x[-4:]+c

Partial test online
This requires a terminal to run, otherwise you'll get this error:
termios.error: (25, 'Inappropriate ioctl for device')

Ungolfed
import sys,tty
tty.setraw(sys.stdin.fileno())
x=0
while 1:
 c=sys.stdin.read(1)
 sys.stdout.write(c)
 sys.stdout.flush()
 if"hello"[x]==c:
    x+=1
    if x>5:break
 else:x=0

x="" and while"hello"!=x[-5:]:c=sys.stdin.read(1);o.write(c);o.flush();x=x[-4:]+c to save some bytes

but x+=c will fail on an infinite stream

@ovs I fixed it. The OP clarified the specs.

It's much harder in python than I expected!

Yeah, Python doesn't have nice input streaming.

In the second one, replace sys with sys as s and subsequently replace all the sys in the code with s. That'll bring down the size to 135 bytes.

Java 7, 122 118 124 123 150 141 bytes
void c()throws Exception{String a="aaaaa";for(int b;!a.equals("hello")&(b=System.in.read())>=0;a=a.substring(1)+(char)b)System.out.write(b);}

Now stops when the end of the stream is reached. Now handles infinite input without running out of memory.

I bet this can´t handle infinite input.

@Titus fixed...

I downvoted without seeing write being used instead of print. I can't undo my downvote, sorry for that :(

C (gcc), 73 72 65 63 69 77 72 71 bytes
It now terminates on the end of the input as well as handling input like this;
I once had a horse called hellhellopina.

i;main(c){for(;~(c=getchar())&i-5;i=putchar(c)^"hello"[i]?c=='h':i+1);}

Try it online!

Mathematica, 107 bytes
i="";EventHandler[Dynamic@i,"KeyDown":>(i=i<>CurrentValue@"EventKey";If[StringTake[i,-5]=="hello",Exit[]])]

The output becomes a field where the user can infinitely type text (including newlines) until the last 5 characters are equal to "hello"; at that point, it exits.

Ruby, 51 bytes
x="";$><<x[-1]while/hello./!~x=x[/.{0,5}$/]+$<.getc

Does not expect newlines
Works with infinite input

AHK, 116 bytes
Loop,Read,%1%
{a=%A_LoopReadLine%`n
Loop,Parse,a
{Send % c:=A_LoopField
If((f:=c SubStr(f,1,4))=="olleh")
ExitApp
}}

There's nothing clever or magical in there, really. The variable %1% is the first passed argument and should be a file path with the stream. The file must be saved as it is updated but the code will read to the end even if it expands after the reading starts.

brainfuck, 281 bytes
>++++++++[<+++++++++++++>-]>++++++++++[<++++++++++>-]<+>>+++++++++[<++++++++++++>-]>++++++++++[<+++++++++++>-]<+>+[[[[[,.<<<<[->>>>->+<<<<<]>>>>>[-<<<<<+>>>>>]<],.<<<[->>>->+<<<<]>>>>[-<<<<+>>>>]<],.<<[->>->+<<<]>>>[-<<<+>>>]<],.<<[->>->+<<<]>>>[-<<<+>>>]<],.<[->->+<<]>>[-<<+>>]<]

I'm not sure why, but I just felt like brainfuck was the right thing to do this. Doesn't require infinite memory, and can output forever.
Explained
Set up the buffers with helo
This is done Naively; sue me
>++++++++[<+++++++++++++>-]     h
>++++++++++[<++++++++++>-]<+>   e
>+++++++++[<++++++++++++>-]     l
>++++++++++[<+++++++++++>-]<+>  o

THE MAIN LOOP
+
[ matches o
    [ matches l
        [ matches l
            [ matches e
                [ matches h
                    ,. Read a character and immediently write it
                    <<<<[->>>>->+<<<<<] Subtract it from h
                    >>>>>[-<<<<<+>>>>>] Correct the h
                    < Terminate this part of the loop if it matches h
                ]
                ,. Same as above
                <<<[->>>->+<<<<] Subtract it from e
                >>>>[-<<<<+>>>>] Correct the e
                < Terminate this part of the loop if it matches e
            ]
            ,. Same as above
            <<[->>->+<<<] Subtract it from l
            >>>[-<<<+>>>] Correct the l
            < Terminate this part of the loop if it matches l
        ]
        ,. Same as above
        <<[->>->+<<<] Subtract it from l
        >>>[-<<<+>>>] Correct the l
        < Terminate this part of the loop if it matches l
    ]
    ,. Same as above
    <[->->+<<] Subtract it from o
    >>[-<<+>>] Correct the o
    < Terminate this part of the loop if it matches o
]

Try it online!

I was gonna do it like this but then I realized that this outputs the zero byte infinitly for input that doesn't contain "hello": https://tio.run/nexus/brainfuck#jYsxCoAwDEWv0v0bTxBykZChoOAiTg6evrZppR0U/NvLe0mCNmWMEzLpNMpsGCJ4f/z@a4/QsmnmPCXJI0EBtgKi5AAHY/PSw9ZZrzA0JamFPR4/bZburBr4PaXrOMMWl7CvId4

This also fails on ahehellob.

AWK, 72 bytes
BEGIN{RS="(.)"
h="olleh"}{printf RT
if("hello"==h=substr(h RT,2,6))exit}

I know, I have another AWK solution,  but this is using a different approach with no loop, inspired by some of the other solutions.
As per @manatwork this one appears more AWKish :)

Actually by “awkish” I meant the use of typical pattern{action} syntax instead of if. ;)

Ah... yeah... I try to use every aspect of AWK that I seems appropriate at the time. So the most common pattern I use is the empty-pattern which just applies to every 'line'.

Chip, 154 bytes
H.G~.F~.E.D~.C~.B~.A~.AabB
Z<Z~<Z~<Z<Z~<Z~<Z-<Z-<CcdD
Z<Z~<Z~<Z<Z~<Z~<Z-<Z-<EefF
Z<Z~<Z~<Z<Z-<Z~<Z-<Z~<GghH
Z<Z~<Z~<Z<Z~<Z-<Z-<Zv'
 `--^--^-^--^--^--^-^~t

Try it online!
Chip is a language inspired by integrated circuits, and designed to operate on the individual bits of a byte stream.
How it works
The rightmost 4x4 block of characters is the simple Chip cat program. We already need linebreaks for the other stuff, so we suffer no penalty spreading this across multiple lines. It simply copies input to output, one byte at a time.
The remaining elements are dedicated to detecting 'hello' and terminating once it is found.
The algorithm I use is to locate differences between the string 'hello' and the five most recent bytes. If no differences are found, then we have seen 'hello' and the program will terminate itself with element t.
In the actual implementation, there are eight sets of columns, one for each bit of the input. Let's look at the 0x8 bit, accessed by element D:
D~.
Z~<
Z~<
Z-<
Z~<
 -^-

The top row is looking at the current byte. In this case, its value, D is inverted by ~ and propagated into the wire along the right. So, if this bit is not set in the input, we know it can't be the 'o' at the end of 'hello', and we can't yet terminate. We then look to the previous value in row 2, then the one before that in row 3, and so on. In the fourth row, we see a - instead of a ~, meaning that we don't invert it. This is because the 'e' of the keyword does not have this bit set, unlike all the other letters.
All this means that the wire along the right is activated if there is a discrepancy in the 0x8 bit of the last few bytes. The results for all bits are then collected along the bottom row, and if any of them show a discrepancy, we know to not yet terminate.
If the termination keyword were longer, we would simply need to add one row per additional byte.

Python 105
Hopefully this count is fair, I've included what you need to set it up. Not the characters for the usage:
def c():
 b=yield
 while b!='hello':
  b+=yield b[-1]
  if len(b)==6:
   b=b[1:]
i=c()
i.next()

Usage would be something like this:
import string
import random

consumer = c()
consumer.next()
while True:
    try:
        char = random.choice( string.ascii_letters )
        print consumer.send( char )
    except GeneratorExit:
        print 'stopped'

Input has to be an infinite text stream or file. You can't make a function that takes one char at a time and call that good.

@mbomb007 that while loop generates an infinite stream of random letters. That code will run forever if 'h', 'e', 'l', 'l', 'o' isn't generated. There will be no memory errors

@mbomb007 not sure how else you generate/consume an infinite stream if not a char at a time. Please enlighten me.

But that loop isn't part of your code/solution. You don't get to generate your own stream of arbitrary input, you have to take it in the form the OP said, which is from stdin as an infinite stream or file.

C(bcc gcc), 66 bytes
main(b,c){for(;~(c=getchar())&&b-'hell'|putchar(c)-'o';b=b<<8|c);}

the trick it is easy: We can consider the variable b as one buffer of 4 characters
so, each char it read, it push it in the b buffer in this way b=b<<8|c.
In b-'hell' it checks in b buffer there is "hell", if there is, and there is c=='o' too => it end the loop.
It seems even in gcc in http://ideone.com/uPSMo6 it compile run and stop well.
For to be ok the C language compiler I believe has to translate in the way:
1) the first argument 'b' it is argc so initialized with number of arguments one give to program
2) int is 4 characters of 8 bit
3) the 4 characters in quote 'abcd' are translated in one int/unsigned as in '1234'  the number 0x31323334
Other above it assume
4) putchar() can not fail in write its character in stdout
i proposed this 67 bytes solution too but they said it is not ok.
z(c,b){for(;putchar(c=getchar()),~c&&b-0x68656c6c|c-'o';b=b<<8|c);}

Where are all comments here? Who had to cancel all comment in this place? But what is this a site of bully and for bulling people? Who had given to the code above the valuation -1 and why?

I deleted the comments because they didn't serve a purpose anymore. Asking people why they downvoted is pointless. It's unlikely the downvoter would actually see your comment, and even if they did, they would have left a comment already if they wanted to explain.

There is a character that is as ➡  or -> that is read as -1 from getchar() and keyboard msdos window

No. getchar reads a character  (8 bits on MS-DOS or Windows) and returns a signed 32-bit integer between 0 and 255. -1 is returned only when the end of the file (or stream) is reached.

I copy and paste that char, the program stop when it read it, the value printed from printf("%d,c) was -1; my program, all C program. Possibly something was wrong with the old sys etc

→ number char 26; here if someone push that char in the keyboard as input in one program as alt-026 the program receive EOF as one push  EOF

I am aware that Ctrl-Z sends 0x1A which is interpreted as EOF in a Windows terminal. I told you that in a previous comment. But the sent byte is interpreted by the terminal, which just closes them stream. The 0x1A is never sent to the program.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Triangular Manhattan Distance
The Manhattan distance on a regular grid is the number of orthogonal steps one needs to take to reach one cell from another. Orthogonal steps are those that go through the edges of the grid cells (as opposed to the corners, which would give us the Chebyshev distance).
We can define a similar distance on other grids, for example the triangular grid. We can address the individual cells in the grid with the following indexing scheme, where each cell contains an x,y pair:
    ____________________________________...
   /\      /\      /\      /\      /\
  /  \ 1,0/  \ 3,0/  \ 5,0/  \ 7,0/  \
 / 0,0\  / 2,0\  / 4,0\  / 6,0\  / 8,0\
/______\/______\/______\/______\/______\...
\      /\      /\      /\      /\      /
 \ 0,1/  \ 2,1/  \ 4,1/  \ 6,1/  \ 8,1/
  \  / 1,1\  / 3,1\  / 5,1\  / 7,1\  /
   \/______\/______\/______\/______\/___...
   /\      /\      /\      /\      /\
  /  \ 1,2/  \ 3,2/  \ 5,2/  \ 7,2/  \
 / 0,2\  / 2,2\  / 4,2\  / 6,2\  / 8,2\
/______\/______\/______\/______\/______\...
\      /\      /\      /\      /\      /
 \ 0,3/  \ 2,3/  \ 4,3/  \ 6,3/  \ 8,3/
  \  / 1,3\  / 3,3\  / 5,3\  / 7,3\  /
   \/______\/______\/______\/______\/___...
   /\      /\      /\      /\      /\
  .  .    .  .    .  .    .  .    .  .
 .    .  .    .  .    .  .    .  .    .

Now the Manhattan distance on this grid is again the minimal number of steps across edges to get from one cell to another. So you can move from 3,1 to 2,1, 4,1 or 3,2, but not to any other triangle, since those would be crossing points rather than edges.
For instance, the distance from 2,1 to 5,2 is 4. The shortest path is generally not unique, but one way to make the distance in 4 steps is:
2,1 --> 3,1 --> 3,2 --> 4,2 --> 5,2

The Challenge
Given two coordinate pairs x1,y1 and x2,y2 from the above addressing scheme, return the Manhattan distance between them.
You may assume that all four inputs are non-negative integers, each less than 128. You may take them in any order and arbitrarily grouped (four separate arguments, a list of four integers, two pairs of integers, a 2x2 matrix, ...).
You may write a program or a function and use any of the standard methods of receiving input and providing output.
You may use any programming language, but note that these loopholes are forbidden by default.
This is code-golf, so the shortest valid answer – measured in bytes – wins.
Test Cases
Each test case is given as x1,y1 x2,y2 => result.
1,2 1,2 => 0
0,1 1,1 => 1
1,0 1,1 => 3
2,1 5,2 => 4
0,0 0,127 => 253
0,0 127,0 => 127
0,0 127,127 => 254
0,127 127,0 => 254
0,127 127,127 => 127
127,0 127,127 => 255
75,7 69,2 => 11
47,58 36,79 => 42
77,9 111,23 => 48
123,100 111,60 => 80
120,23 55,41 => 83
28,20 91,68 => 111
85,107 69,46 => 123
16,25 100,100 => 159
62,85 22,5 => 160
92,26 59,113 => 174
62,22 35,125 => 206

Are loopholes that received net negative ratings to be included among the official loopholes?

@DavidC No. From the loophole question: "[...] the loophole described in any answer which is at +5 or above and has at least twice as many upvotes as downvotes may be taken to be deemed to be unacceptable to the community"

Are we allowed to take a fifth input, which starts at 0 by default (the result)? Then I won't need to add (a,b,x,y)->c(a,b,x,y,0) (calling separated method c with the four arguments and 0 as fifth argument) to my answer.

@KevinCruijssen No sorry. Additional, fixed arguments are a bit too easily abusable (and just allowing 0 as a special case seems weird).

@MartinEnder Ok, thought so, but can never hurt asking. In that case my 190-byte answer remains. Even though I answered halve a year ago, one test case was failing. Came across the question again just now, and was able to fix the bug in my answer.

JavaScript (ES6), 84 78 bytes
Saved 6 bytes thanks to Neil
(a,b,c,d,x=a>c?a-c:c-a,y=b>d?b-d:d-b,z=x>y?x:y)=>y+z+(x+z&1?a+b+(b>d)&1||-1:0)

Test cases

let f =

(a,b,c,d,x=a>c?a-c:c-a,y=b>d?b-d:d-b,z=x>y?x:y)=>y+z+(x+z&1?a+b+(b>d)&1||-1:0)

console.log(f(  1,  2,  1,  2)); // => 0
console.log(f(  0,  1,  1,  1)); // => 1
console.log(f(  1,  0,  1,  1)); // => 3
console.log(f(  2,  1,  5,  2)); // => 4
console.log(f(  0,  0,  0,127)); // => 253
console.log(f(  0,  0,127,  0)); // => 127
console.log(f(  0,  0,127,127)); // => 254
console.log(f(  0,127,127,  0)); // => 254
console.log(f(  0,127,127,127)); // => 127
console.log(f(127,  0,127,127)); // => 255
console.log(f( 75,  7, 69,  2)); // => 11
console.log(f( 47, 58, 36, 79)); // => 42
console.log(f( 77,  9,111, 23)); // => 48
console.log(f(123,100,111, 60)); // => 80
console.log(f(120, 23, 55, 41)); // => 83
console.log(f( 28, 20, 91, 68)); // => 111
console.log(f( 85,107, 69, 46)); // => 123
console.log(f( 16, 25,100,100)); // => 159
console.log(f( 62, 85, 22,  5)); // => 160
console.log(f( 92, 26, 59,113)); // => 174
console.log(f( 62, 22, 35,125)); // => 206

Initial recursive solution, 100 88 81
Saved 12 bytes thanks to ETHproductions
Saved 7 bytes thanks to Neil
f=(a,b,c,d,e=b==d|a+b+(b>d)&1)=>a-c|b-d&&f(e?a+1-2*(a>c):a,e?b:b+1-2*(b>d),c,d)+1

How it works
Although it still essentially applies to the current version, the following explanation more specifically refers to the initial version:
f=(a,b,c,d)=>b-d?a+b+(b>d)&1?f(a+1-2*(a>c),b,c,d)+1:f(a,b+1-2*(b>d),c,d)+1:Math.abs(a-c)

Going from (x0, y) to (x1, y) is trivial because we can go across lateral edges all the way from the source triangle to the target one. The Manhattan distance in this case is | x0 - x1 |.
The tricky part is the vertical steps. To go from row y0 to row y1, we have to take these two parameters into account:

The orientation of the current triangle
Whether y0 is less or greater than y1

The orientation of a triangle is given by the parity of x + y:

if it's even, the triangle is up-pointing
if it's odd, the triangle is down-pointing

We can go downwards from an up-pointing triangle (useful when y0 < y1) and upwards from a down-pointing triangle (useful when y0 > y1).
By combining the orientation of the triangle with the comparison between y0 and y1, we get the formula x + y0 + (y0 > y1 ? 1 : 0) whose result is even if we can go in the desired direction and odd if not.
If we can't reach the next row directly, we first need to get a correct alignment by updating x:

if x is not yet equal to x1, we definitely want to move in the correct direction, so we increment it if x is less than x1 and we decrement it if x is greater than x1
if x already equals x1, we can either increment or decrement it

Test cases

f=(a,b,c,d)=>b-d?a+b+(b>d)&1?f(a+1-2*(a>c),b,c,d)+1:f(a,b+1-2*(b>d),c,d)+1:Math.abs(a-c)

console.log(f(  1,  2,  1,  2)); // => 0
console.log(f(  0,  1,  1,  1)); // => 1
console.log(f(  1,  0,  1,  1)); // => 3
console.log(f(  2,  1,  5,  2)); // => 4
console.log(f(  0,  0,  0,127)); // => 253
console.log(f(  0,  0,127,  0)); // => 127
console.log(f(  0,  0,127,127)); // => 254
console.log(f(  0,127,127,  0)); // => 254
console.log(f(  0,127,127,127)); // => 127
console.log(f(127,  0,127,127)); // => 255
console.log(f( 75,  7, 69,  2)); // => 11
console.log(f( 47, 58, 36, 79)); // => 42
console.log(f( 77,  9,111, 23)); // => 48
console.log(f(123,100,111, 60)); // => 80
console.log(f(120, 23, 55, 41)); // => 83
console.log(f( 28, 20, 91, 68)); // => 111
console.log(f( 85,107, 69, 46)); // => 123
console.log(f( 16, 25,100,100)); // => 159
console.log(f( 62, 85, 22,  5)); // => 160
console.log(f( 92, 26, 59,113)); // => 174
console.log(f( 62, 22, 35,125)); // => 206

That's... a lot of very small math operations... But couldn't you skip the n variable altogether and just add 1 to the result of each iteration? (90 chars I think)

@ETHproductions To be honest, I posted it without any serious golfing. But that's definitely the first thing to do. Thanks!

Also, I think the operator precedence of & means you can do a+b+(b>d)&1 to save 2 bytes

Got it down to 81, I think: f=(a,b,c,d,e=b==d|a+b+(b>d)&1)=>a-c|b-d&&f(e?a+1-2*(a>c):a,e?b:b+1-2*(b>d),c,d)+1

I think it might be possible to save another byte using some clever currying.

@Neil c=>d=>f=(a,b,e=b==d|a+b+(b>d)&1)=>a-c|b-d&&f(e?a+1-2*(a>c):a,e?b:b+1-2*(b-d))+1 for 79 I think

Add y to z to reduce the nonrecursive version to 78 bytes: z=x>y?x-y:0 becomes z=x>y?x:y, y*2+z becomes y+z and x+y+z becomes x+z.

@Neil Very good catch!

Python 2, 74 bytes
lambda x,y,X,Y:abs(y-Y)+max(x-X,X-x,abs(y-Y)+((x+y+X+Y)%-2)**(x^y^(Y>=y)))

Can you, please, explain this part: **(x^y^(Y>=y)) ?

@DeadPossum Moving by a distance 1 vertically can take either 1 or 3 moves; there's no way to tell by just looking at parities so you have to compare the y values.

Batch, 99 bytes
@cmd/cset/a"x=%3-%1,x*=x>>31|1,y=%4-%2,w=y>>31,y*=w|1,z=x+(y+x&1)*(-(%1+%2+w&1)|1)-y,z*=z>>31,x+y+z

Explanation: A horizonal-only motion simply takes the absolute x-coordinate difference. For large enough x, the vertical motion only takes one extra step per absolute y-coordinate difference, but for small x, it takes four extra steps per two y-coordinate difference, plus one or three steps for an odd difference. This is calcluated as two steps per difference plus a correction factor. The larger of the corrected two steps and the sum of absolute differences is then the result, although this is itself calculated as the larger of the corrected absolute y-coordinate difference and the absolute x-coordinate distance added to the uncorrected absolute y-coordinate difference.

@cmd/cset/a" - Evaluates comma-separated expressions and prints the last one
x=%3-%1,x*=x>>31|1 Calculates \$x=|x_2-x_1|\$
y=%4-%2,w=y>>31,y*=w|1 Calculates \$w=y_1>y_2\$ and \$y=|y_2-y_1|\$
z=x+(y+x&1)*(-(%1+%2+w&1)|1)-y Correction factor \$c=(y+(x\bmod2))(1-2((x_1+y_1+w)\bmod2)), z=x+c-y\$
z*=z>>31,x+y+z Calculates \$max(x,y-c)+y = x+y-min(0,x+c-y)\$

05AB1E, 24 bytes
Port of my Pyth answer, which in turn uses roughly the same approach as feersum's Python answer. Takes input as a list of pairs of coordinates, \$(x_1, x_2), (y_1, y_2)\$. Fixed a bug for +1 byte, then fixed another mistake for +1, but which yielded the correct result for all test cases...
ÆÄ`©I˜OÉ(IøнOIθD{Q+m+M®+

Try it online!
Breakdown

ÆÄ`©I˜OÉ(IøнOIθD{Q+m+M®+    Full program. I represents the evaluated input.
ÆÄ                          Reduce the pairs by subtraction, take the absolute values.
  `©                        Dump them separately onto the stack and store the second
                            one, |y1-y2| in the register C.
    I˜O                     Push the sum of flattened input onto the stack.
       É(                   Take its parity and negate it.
         Iøн                Push [x1, y1].
            O               Take x1+y1 (sum them).
             IθD{Q          Then check if the second pair is sorted (y1 ≤ y2).
                  +         And sum that with x1+y1.
                   m        Exponentiate. Push the parity above ** the result.
                    +       And add the second absolute difference to that.
                     M®+    As a result, push the largest number on the stack
                            plus the value stored in register C.

I'm not 100% sure, but can't you change the © to D and remove the ®? It seems to work for the case currently in your TIO, but I'm not sure if it follows the same path for every case.

@KevinCruijssen EDIT: No, because M's behaviour would be affected by this. Fails for [[0, 127], [0, 0]].

Jelly, 24 bytes
⁴<³¬Ḋ;³S
SḂN*¢+ḊḤ$
ạµS»Ç

Try it online!
Let’s call the input \$(x,y),(X,Y)\$. I worked from feersum's formula:
\begin{align*}
d &= |y-Y|+\max(|x-X|,|y-Y|+((x+y+X+Y)\bmod -2)^{x \oplus y \oplus (Y \geq y)}) \\
&= |y-Y|+\max(|x-X|,|y-Y|+[-(|x-X|+|y-Y| \bmod 2)]^{x + y + (Y \not< y)}) \\
&= \max(|x-X|+|y-Y|,2|y-Y|+[-(|x-X|+|y-Y| \bmod 2)]^{(Y \not< y) + x + y}).
\end{align*}
The first line computes \$¢ = (Y \not< y)+x+y\$, the exponent in the formula.
The last line first computes \$L=[|x-X|, |y-Y|]\$ and then computes the maximum of \$\text{sum}(L)\$ and \$f(L)\$, where \$f\$ is the function on the middle line.
The middle line, given \$L=[a, b]\$, computes \$-((a+b)\bmod 2)\$, takes that to the \$¢\$'th power, then adds \$2b\$.

Python 2, 74 72 71 bytes
lambda c,a,d,b:abs(a-b)+abs(a+(-c-a)/2-b-(-d-b)/2)+abs((c+a)/2-(d+b)/2)

Try it online! Link includes test cases. Edit: Saved 2 bytes thanks to @JoKing. Saved a further byte thanks to @Mr.Xcoder. Based on the following formula I found in this question:
$$ \left|a_i-b_i\right|\;+\;\left|\left(a_i-\left\lfloor\frac{a_j}2\right\rfloor\right)-\left(b_i-\left\lfloor\frac{b_j}2\right\rfloor\right)\right|\;+\;\left|\left\lfloor\frac{a_j+1}2\right\rfloor-\left\lfloor\frac{b_j+1}2\right\rfloor\right| $$
The coordinate systems differ in three ways; the coordinates are exchanged (which explains my somewhat strange parameter name order), the coordinates are angled at \$120^\circ\$ rather than \$90^\circ\$ (which explains the two additions) and the coordinates in the linked question use inferior 1-indexing. Since we're taking differences this cancels out most of the time and we are left with:
$$ \left|a_i-b_i\right|\;+\;\left|\left(a_i-\left\lfloor\frac{a_j+1}2\right\rfloor\right)-\left(b_i-\left\lfloor\frac{b_j+1}2\right\rfloor\right)\right|\;+\;\left|\left\lfloor\frac{a_j}2\right\rfloor-\left\lfloor\frac{b_j}2\right\rfloor\right| $$
This can then be golfed by noting that \$ -\lfloor\frac{a_j+1}2\rfloor = \lfloor\frac{-a_j}2\rfloor \$.

You can make it a one-liner by removing the newline

lambda c,a,d,b:abs(a-b)+abs(a+-(c+a)/2-b--(d+b)/2)+abs((c+a)/2-(d+b)/2) should save 3 bytes.

racket/scheme, 214 bytes
(define(f x y X Y)(let m((p x)(q y)(c 0))
(let((k(+ c 1))(d(- Y q)))
(cond((= 0(- X p)d)c)
((and(> d 0)(even?(+ p q)))(m p(+ q 1)k))
((and(< d 0)(odd?(+ p q)))(m p(- q 1)k))
((< p X)(m(+ p 1)q k))
(else(m(- p 1)q k))))))

Java 8, 157 190 188 144 142 141 127 125 bytes
(a,b,x,y)->{int r=0,c=1,z=1;for(;(c|z)!=0;r--)if((z=y-b)*z<(c=x-a)*c|a%2!=b%2?z<0:z>0)b+=z<0?-1:1;else a+=c<0?-1:1;return~r;}

+33 bytes (157 → 190) due to a bug fix.
-44 bytes (188 → 144) converting the recursive method to a single looping method.
-16 bytes thanks to @ceilingcat.
Explanation:
Try it here.
(a,b,x,y)->{        // Method with four integers as parameter and integer return-type
                    // (a=x1; b=y1; x=x2; y=y2)
  int r=0,          //  Result-integer `r`, starting at 0
      c=1,z=1;      //  Temp integers for the differences, starting at 1 for now
  for(;(c|z)!=0;    //  Loop until both differences are 0
      r--){         //    After every iteration: decrease the result `r` by 1
    if((z=y-b)      //   Set `z` to y2 minus y1
       *z<          //   And if its squared value is smaller than:
          (c=x-a)   //    Set `c` to x2 minus x1
                 *c //    And square it as well
       |a%2!=b%2?   //   OR if the triangle at the current location is facing downwards
         z<0        //       and we have to go upwards,
        :z>0)       //      or it's facing upwards and we have to go downwards:
      b+=z<0?-1:1;  //    In/decrease y1 by 1 depending on where we have to go
    else            //   Else:
     a+=c<0?-1:1;}  //    In/decrease x1 by 1 depending on where we have to go
  return~r;         //  Return `-r-1` as result

Pyth, 31 28 bytes
Uses roughly the same approach as in feersum's Python answer. Takes input as a list of pairs of coordinates, \$(x_1, x_2), (y_1, y_2)\$. Fixed a bug for -1 byte.
+eKaMQg#hK+eK^%ssQ_2+shCQSIe

Try it here! or Try the test suite!
Breakdown

+eKaMQg#hK+eK^%ssQ_2xxFhCQSIe     Full program. Q = eval(input()).
  KaMQ                            Store the differences [|x1-x2|, |y1-y2|] in K.
 e                                Retrieve the latter (|y1-y2|).
+     g#                          And add it to the greatest value between:
        hK                          - The head of K (|x1-x2|)
          +                         - And the result of adding:
           eK                           The end of K (|y1-y2|).
             ^                      - with the result of exponentiating:
              %ssQ_2                    The sum of the flattened Q, modulo -2.
                                        Yields -1 if x1+x2+y1+y2 is odd, 0 otherwise.
                    xxFhCQSIe       - by the result of this expression:
                       hCQ              Transpose Q and get the head (x1, y1).
                     xF                 Reduce by bitwise XOR.
                          SIe           And check if the list [y1, y2] is sorted.
                    x                   After which, xor the result by the bool (0/1).

Jelly, 22 .. 16 15 bytes
ṭH,‘H_ɗɗ@+¥ḞIAS

Try it online!
Try all test cases.
Uses @Neil's method in this answer which uses a modified formula from this math.SE question.
Takes the coordinates as arguments y1, y2 and x1, x2.

05AB1E, 16 bytes
Uses a modified version of Neil's answer, optimised for stack-based languages like 05AB1E.  Takes input as two pairs of coordinates, \$(x_1, x_2), (y_1, y_2)\$, separated by a newline from STDIN. Initially I merged that with my other 05AB1E answer but then decided to post it separately because it's very, very different.
+D(‚2÷Æ`²Æ©+®)ÄO

Try it online! or Try the test suite! (Uses a slightly modified version of the code (® instead of ²), courtesy of Kevin Cruijssen)

Nice answer! Not something to golf, but when you change ©+® to DŠ+ it's easier to set up a test suite. ;) Here is that test suite, and all test cases are indeed succeeding (ignore the messy header ;p).

@KevinCruijssen I had that as an alternate version, but it didn't occur to me that I could write a test suite... Thanks, I'll add it

@KevinCruijssen I golfed off two more (very obvious...!) bytes, and succeeded breaking the test suite compatibility even more, so I kept it as-is :P Thanks for the edit, by the way.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/