Comprobador de equipo de moto!

36

Algunos de ustedes pueden estar familiarizados con la forma en que cambia una motocicleta. Pero para aquellos que no, se ve así

6 6

5 5

4 4

3

2

norte

1

Ahora quiero saber en qué equipo estoy después de realizar algunos cambios hacia arriba y hacia abajo. El programa debería funcionar desde neutral.

Entrada de muestra:

V^^

Salida de muestra:

2

Como puede ver, bajé una vez de N a 1 y cambié dos veces a segunda velocidad.

Este es un código de golf. La respuesta más corta en bytes gana.

Nota: La entrada puede tener 2 caracteres. Puede ser U y D para subir y bajar o lo que quieras , tiene que ser una cadena . No puedes cambiar más allá de la 1ra o 6ta marcha. Si está en sexto y sube de nuevo, permanecerá en sexto. ¡Buena suerte!

Martijn Vissers
fuente
55
La próxima vez, publique su desafío en el sandbox para obtener comentarios antes de publicarlo en main
fəˈnɛtɪk
1
@seshoumara, los únicos dos requisitos son que debe ser una cadena y que solo puede ingresar 2 caracteres. Entonces podría usar una nueva línea como personaje. pero si lo usaras por otra razón, realmente no me importa. Sería interesante ver lo que tienes en mente. pero dé una breve explicación de por qué lo ha hecho así si lo hace. GL!
Martijn Vissers
44
It's a shame this doesn't account for the half-step shift between 1 and N. It'd be neat to be able to not only go 2 N 1 N 2 3, but also go 2 1 N 2 3
Cort Ammon
2
I agree to @CortAmmon - there is a single shift between 1 and 2. It's half shift where the neutral is.
Džuris
2
not all motorcycles shift like this. Most clutchless motorcycles shift in N-1-2-3-4 (or N-1-2-3 on some very ancient vehicles). They don't have gear 5 or 6 and use a round gear, i.e. when it's 4 then increasing the gear will make it wrap around to N.
phuclv

Respuestas:

15

JavaScript (ES6), 49 48 47 46 bytes

Expects:

  • 1 for down
  • 7 for up
f=([c,...s],g=2)=>c?f(s,g-c&7||g):'1N'[--g]||g

Formatted and commented

f = (                   // f is a recursive function which takes:
  [c,                   // - c = next character in input string
      ...s],            // - s = remaining characters
  g = 2                 // - g = current gear, with default = neutral = 2
) =>                    //
  c ?                   // if there's still a character to process:
    f(                  //   do a recursive call with:
      s,                //     - the remaining characters
      g - c & 7 ||      //     - the updated gear if it is valid
      g                 //       or the previous gear if not
    )                   //
  :                     // else:
    '1N'[--g] ||        //   decrement g and output '1' for g = 0, 'N' for g = 1,
    g                   //   or simply the corresponding digit for other values

Gears are mapped as follows:

g MOD 8 = 0 1 2 3 4 5 6 7
          ---------------
gear    = X 1 N 2 3 4 5 6       (where 'X' is an invalid state)

Which allows us to easily check the validity of the current gear with:

(g & 7) != 0

Demo

Arnauld
fuente
7

05AB1E, 22 20 bytes

Îvy<+®‚Z5‚W}6LÀ'N¸ìè

Try it online!

Explanation

Î                      # push 0 (accumulator) and input
 v         }           # for each in input
  y<+                  # decrement current element and add to accumulator
     ®‚Z               # take maximum of current value and -1
        5‚W            # take minimum of current value and 5
            6L         # push the range [1 ... 6]
              À        # rotate left
               'N¸ì    # prepend the letter "N" producing the list [N, 2, 3, 4, 5, 6, 1]
                   è   # index into this list with the value produced by the loop
Emigna
fuente
6

MATL, 32 28 23 bytes

5 bytes saved thanks to @Luis

'234561N'j!Uq[aA]&Ys0))

This solution uses '2' for up-shift and '0' for down-shift.

Try it at MATL Online

Explanation

'234561N'   % Push the string literal to the stack
j           % Grab the input as a string
!U          % Convert the input to a numeric array based on the characters.
q           % Subtract 1 to turn '2' into 1 and '0' into -1
[aA]        % Push the array [-1 5] to the stack
&Ys         % Compute the cumulative sum using the array [-1, 5] as
            % the upper and lower limits at each point
0)          % Get the last value from the cumulative sum
)           % Use this to index into the initial string literal.
            % Implicitly display the result
Suever
fuente
@Lifeless Updated with an explanation
Suever
Very nice! may i ask why the string is 234561N instead of 1n23456 or 65432n1? I also found a flaw! If you keep upshifting it should stay in 6th gear but it returns N
Martijn Vissers
1
Nice! Didn't know about the limits trick in cumsum
B. Mehta
1
@B.Mehta Me neither! Luis recommended it
Suever
1
@B.Mehta Also, feel free to join us over in the MATL chatroom!
Suever
6

V, 20, 15 bytes

:sil!î¬61énÀxVp

Try it online!

Input is a string of h (up) and l (down) characters.

Thanks to @nmjcman for saving 5 bytes and teaching me about a vim feature I never knew about!

If we could assume the input never goes out of bounds, it would simply be 9 bytes:

¬61énÀxVp

But unfortunately that isn't allowed.

Explanation:

:sil!           " If the cursor goes out of bounds, ignore it and continue
     î          " Run the following keystrokes as V code, rather than vimscript:
      ¬61       "   Insert the string "654321". This will leave the cursor on the '1'
         én     "   Insert an 'n'
           À    "   Run the first arg as V code. This will move left and right a bunch of times
            x   "   Delete whatever character we ended up on
             V  "   Select this whole line,
              p "   And replace it with the character we just deleted
DJMcMayhem
fuente
2
Also, Try it online! V compression. That's cool.
nmjcman101
Actually, I think that this doesn't work because going over or under the 1/6 breaks the macro :/
nmjcman101
Why is the 9 byte answer not allowed?
Albert Renshaw
@AlbertRenshaw It fails if you ever attempt to shift beyond 1st or 6th gear. For example Try it online! should output n, not 1.
DJMcMayhem
Oh I see, I thought by input is always valid you meant non-shifting characters. Still a cool answer even if its invalid
Albert Renshaw
6

Java 7, 106 105 103 bytes

char c(String s){int r=1;for(int c:s.toCharArray())r+=c<99?1:-1;return"1N23456".charAt(r<0?0:r>6?6:r);}

Explanation:

char c(String s){                // Method with String input and character return-type
  int r = 1;                     // Result-index (0-indexed and starting at 1)
  for(int c : s.toCharArray()){  // Loop over all characters in the input String
    r += c < 99 ?                //  If the current character is '^':
           1                     //   Raise the result-index by 1
         :                       //  If it is 'v' instead:
           -1;                   //   Decrease the result-index by 1
  }
  return "1N23456".charAt(       // Return the character based on the return-index:
           r < 0 ?               //  If the result-index is below 0
                  0              //   Use 0 instead
                 : r > 6 ?       //  Else-if the result-index is above 6
                          6      //   Use 6 instead
                         :       //  Else
                          r);    //   Use the result-index
}

Test code:

Try it here.

class M{
  static char c(String s){int r=1;for(int c:s.toCharArray())r+=c<99?1:-1;return"1N23456".charAt(r<0?0:r>6?6:r);}

  public static void main(String[] a){
    System.out.println(c("v^^"));
    System.out.println(c("^^^^^^^^"));
    System.out.println(c("vvvv^^^vvvv"));
    System.out.println(c("^v^v^v^v"));
  }
}

Output:

2
6
1
N
Kevin Cruijssen
fuente
5

Haskell, 59 53 51 Bytes

("1N23456"!!).foldl(\l c->max 0$min 6$l+read[c]-1)1

Uses 0 for down and 2 for up. Usage example:

(("1N23456"!!).foldl(\l c->max 0$min 6$l+read[c]-1)1) "0002"

Thanks to @xnor for taking off 6 bytes! Also, turns out I don't need a function name or parentheses so that's another 2 bytes.

user1472751
fuente
If you take the input chars as 0 and 2, you can do read[c]-2.
xnor
Welcome to PPCG! Anonymous functions are fine too, so you don't need the g=.
Laikoni
@Laikoni I'd have to wrap it in parentheses, right? That wouldn't change the byte count so I thought I'd leave the g= because it's clearer
user1472751
@user1472751 You don't need the parens.
Esolanging Fruit
4

JavaScript (ES6), 48 58 bytes

s=>"1N23456"[[1,...s].reduce((a,b)=>a?a<6?+b?a+1:a-1:6:0)]

Usage

Assign it to a function, and then call it. Input is a string containing a 1 for an upshift, and a 0 for a downshift.

f=s=>"1N23456"[[1,...s].reduce((a,b)=>a?a<6?+b?++a:a--:6:0)]
f("011")
-> "2"
f("0")
-> "1"
f("01")
-> "N"
Luke
fuente
f(0) returns 1 not N... and your code returns undef if you shift up from 6 or down from 1
fəˈnɛtɪk
Good catch. Fixed at cost of two bytes
Luke
Doesn't work input such as f("001") which should return N (gear down to 1, gear down staying at 1, gear up to N)
Emigna
Not supposed to loop around. It should stay at 6 if upshifted from 6 and stay at 1 if downshifted from 1. Also, it still gives undef if you downshift from 1
fəˈnɛtɪk
4

PHP 7.1, 71 bytes

for(;$c=$argv[1][$i++];))$g=max(-1,min($g+=$c<=>X,5));echo N234561[$g];

shifts $g from -1 to 5, uses negative string offset for first gear.
Run with -nr, provide shifting string as command line argument.

Titus
fuente
4

Jelly, 17 14 bytes

1;r2ị$¥/CỊ¡o”N

Uses 6 for up and0 for down.

Try it online!

How it works

1;r2ị$¥/CỊ¡o”N  Main link. Argument: s (string of 6's and 0's)

1;              Prepend a 1 (integer) to the string/character array s.
       /        Reduce the result by the following dyadic link.
                Let's call the arguments x and y.
      ¥           Create a dyadic chain of 2 links:
  r                 Construct the range [x, ..., y] (increasing or decreasing).
                    y will be a character, but 'r' casts both argument to int.
                    This is intended for use with floats, but it works just as well
                    when the argument is a digit.
     $              Create a monadic chain of two links:
   2ị                 Take the second element of the constructed range.
                  When y = 6 > x, this gives x + 1.
                  When y = 0 < x, this gives x - 1.
                  When y = x, the range is a singleton array, so this gives x.
          ¡     Conditional application:
         Ị        If the previous result is insignificant (0 or 1):
        C           Subtract it from 1.
                This swaps 0 and 1 without affecting the other potential outcomes.
           o”N  Logical OR with 'N', replacing 0 with that character.
Dennis
fuente
2

Ruby, 58 bytes

->s{a=1;s.chars{|b|a-=[a<=>0,a<=>6][b<=>?v]};"1N23456"[a]}

Expected input is 'v' for a downshift and '^' for upshift

G B
fuente
2

Processing JS (modified) 121 bytes

var g="1N23456",a="",c=0; for(var i=0;i<a.length;i++){if(a[i]==="d"&&c>0){c--;}else if(c<6&&a[i]==="u"){c++;}}println(g[c]);

Ungolfed

var g=[1,"N",2,3,4,5,6],a="",c=0;
for(var i=0;i<a.length;i++)
{if(a[i]==="d"&&c>0)
{
    c--;

}else if(c<6&&a[i]==="u")
{
    c++;

}

}
println(g[c]);

Try it online!

I went with PJs since I know it well. The only problem is the version I use is very strictly typed. I can't leave out brackets and lots of other tricks. It is pretty simple. The input should go into the variable a and it takes lowercase u d. The program loops until it hits the end of the string and every iteration it checks to see if it is a u or a d. If it is and it won't try and "shift" past where you can it shifts. At the end I print the results!

Christopher
fuente
If your version allows ternary operators, you might be able to rewrite your ifs in a much more shorter fashion, I think.
Bojidar Marinov
The input should go into the variable a Using hard coded input is not a default input method, see here.
Laikoni
@Laikoni really? That is silly. I don't have any better way. If I have to redo this it will be ~100 bytes longer
Christopher
Can't you simply wrap your code in a function? Eg. void f(String[] a){...} That's hardly 100 bytes.
Laikoni
@Laikoni In Khan Academy ProcessingJS, it is pure JS, and hence doesn't have String or void. But you're right, a function would be way shorter
Kritixi Lithos
2

k, 25 bytes

"1N23456"@{6&0|x+y-92}/1,

It takes input as a string, and uses [ for downshift, and ] for upshift, because they're conveniently situated.

"1N23456"@                / the numbers 0 to 6 are used for the gears,
                          / this turns them into the correct number/letter
                       1, / prepend 1 because this is our initial gear
          {          }/   / fold the function through the list
                          / x is before, y is the next character
                 y-92     / subtract 92, which is between "[" and "]"
                          / "[" becomes -1 and "]" becomes 1
               x+         / add it to what we had before
           6&0|           / use max and min to set boundaries 6 and 0

Examples:

 shift:"1N23456"@{6&0|x+y-92}/1,
 shift"[]]"
"2"
 shift"]]]]]]]]"
"6"
 shift"[[[[]]][[[["
"1"
 shift"[][][][]"
"N"
 shift"[[[[[[[[]"
"N"
 shift"]]]]]]]]["
"5"
zgrep
fuente
2

GNU sed, 89 87 + 1(r flag) = 88 bytes

Because sed has no integer types or arithmetic operations, the solution is arrived at by using regular expressions only.

s:$:65432Nx1:
:
/6x/!s:^U(.*)(.)x:\1x\2:
s:^D(.*)x(.):\1\2x:
t
s:U|D::
t
s:.*(.)x.*:\1:

It works by sliding the pointer x based on each input shift, left (for Up) or right (for Down), along a non-wrapping tape that contains only the cells 65432N1. The answer at the end is the value in the cell left of the pointer.

Example run: or Try it online!

sed -rf gear.sed <<< "UUUUUUD"
5

Explanation:

s:$:65432Nx1:              # assign initial tape and pointer
:                          # start loop
/6x/!s:^U(.*)(.)x:\1x\2:   # if shift 'U', slide `x` to left, but not past the edge
s:^D(.*)x(.):\1\2x:        # if shift 'D', slide `x` to right, -||-
t                          # repeat
s:U|D::                    # if a shift couldn't be applied, delete it "manually",
t                          # and jump to the start of the loop again
s:.*(.)x.*:\1:             # print value left of pointer `x` (answer)
seshoumara
fuente
Here is 76 bytes, but it outputs in unary.
Riley
@Riley Unary, of course! Well, your solution is different, so why not post it!
seshoumara
Yours gave me the inspiration for it. I figured I'd let you use it if you wanted.
Riley
@Riley Then I'll make a separate section with your version and credit you.
seshoumara
I'll just post my own :)
Riley
2

GNU sed, 76 73 bytes

Includes +1 for -r

s/$/1/
:
/1{6}/!s/^U(.*)/\11/
s/^D(.*)1/\1/
t
s/U|D//
t
s/^1$/N/
s/^$/1/

Output is in unary except neutral, which is still N (see this consensus).

Try it online!

This basically counts up and down in unary then converts 1 to N and 0 to 1.

s/$/1/               # add 1 to the end (the starting value)
:                    # loop start
/1{6}/!s/^U(.*)/\11/ # If the string starts with 'U' and doesn't have 6 ones, increment
s/^D(.*)1/\1/        # If the string starts with 'D' decrement (but not past 0)
t                    # if something changed loop back
s/U|D//              # if the U or D couldn't be applied, remove it.
t                    # if something changed loop back
s/^1$/N/             # replace 1 with N
s/^$/1/              # if "0", replace with 1
Riley
fuente
Your sed version can be shorter by 4 bytes I think, if you work with 1 as the starting value, as N, and nothing as 1. s/$/1/;:;/1{6}/!s/^U(.*)/\11/;s/^D(.*)1/\1/;t;s/U|D//;t;s/^1$/N/;s/^$/1/
seshoumara
2

Rebol, 96 93 bytes

f: func[s][g: next"1N23456"parse s[any["D"(g: back g)|"U"(unless tail? x: next g[g: x])]]g/1]

Ungolfed:

f: func [s] [
    g: next "1N23456"
    parse s [
        any [
              "D" (g: back g)
            | "U" (unless tail? x: next g [g: x])
        ]
    ]
    g/1
]

Example usage (in Rebol console):

>> print f "DUU"         
2

>> print f "DDDUU"
2

>> print f "UUUUUUUUU"  
6

>> print f "UUUUUUUUUD"
5
draegtun
fuente
2

><>, 35 bytes

An enthusiastic piece of code that encourages you to drive above the speed limit.

Accepts any two inputs whose code modulo 3 are 0 and 2, for example 0 and 2.
For extra fishiness, I recommend the use of < and >.

1i:0(?;3%1-+:0(?0:6)?6:1go!
1N23456

Explanation :

1i:0(?;3%1-+:0(?0:6)?6:1go!
1                             # initial position
 i                            # read the next char
  :0(?;                       # copies it, test copy against 0, if lower stops (EOF detection)
       3%1-                   # map the char to -1 or 1
           +                  # add it to the position
            :0(?0             # if the new position is lower than 0, set to 0
                 :6)?6        # if the new position is greater than 6, set to 6
                      :1go    # output a character from line 1 at the position
                          !   # loops and skip the position initialisation

You can try it here !

Aaron
fuente
1

SpecBAS - 102

1 g=2: INPUT s$
2 FOR i=1 TO LEN s$
3 g+=(s$(i)="^" AND g<7)-(s$(i)="v" AND g>1)
4 NEXT i
5  ?"1N23456"(g)

Moves the index of the string depending on input and prints the relevant character.

Brian
fuente
1

Pyth, 32 bytes

J1VQ=JhtS[06+J-qNbqNd;?qJ1\N?JJ1

Uses space and newline for down and up.

Explanation

J1VQ=JhtS[06+J-qNbqNd;?qJ1\N?JJ1
J1                                 Initialize J to 1
  VQ                 ;             For each character in the input
            +J-qNbqNd              Increment or decrement J
      htS[06                       Get the middle sorted value of [0,6,J]
    =J                             Assign it to J
                      ?qJ1\N?JJ1   Change 1 to 'N' and 0 to 1

There's almost certainly a better way to do the incrementing and the output.


fuente
1

CJam, 24 22 bytes

"1N23456"1q{~0e>6e<}/=

Uses ( for down and ) for up.

Try it online!

Explanation

"1N23456"               e# Push the string containing all gears
         1              e# Push 1, the initial index
          q             e# Push the input
           {            e# For each character in the input
            ~           e#   Eval that character. ( is decrement and ) is increment.
             0e>        e#   Take the maximum of (0, index)
                6e<     e#   Take the minimum of (6, index)
                   }/   e# (end of block)
                     =  e# Take that index of the string
Business Cat
fuente
1

Batch, 144 bytes

@set/ps=
@set g=1
:l
@if %g% neq %s:~,1% set/ag+=%s:~,1%/3-1
@set s=%s:~1%
@if not "%s%"=="" goto l
@if %g%==1 (echo N)else cmd/cset/ag+!g

Takes input on STDIN, using 0 to go to a lower gear and 6 to go to a higher gear. These numbers were chosen to make it easy to ignore the current gear. Finally if the gear is 1 then N is printed otherwise 0 is converted to 1 and the gear is printed.

Neil
fuente
0

Javascript ES6 nonstrict, 136 120 chars

136 chars for V^

with({get x(){return Math.max(0,Math.min(y,6))},set x(v){y=v}})f=s=>eval(s.replace(/(V)|./g,(m,v)=>`x${"-+"[+!v]}=1,`,y=1)+'"1N"[x]||x')

with({get x(){return Math.max(0,Math.min(y,6))},set x(v){y=v}})
f=s=>eval(s.replace(/(V)|./g,(m,v)=>`x${"-+"[+!v]}=1,`,y=1)+'"1N"[x]||x')
console.log(f("V^^"))

120 chars for -+

with({get x(){return Math.max(0,Math.min(y,6))},set x(v){y=v}})f=s=>eval(s.replace(/./g,m=>`x${m}=1,`,y=1)+'"1N"[x]||x')

with({get x(){return Math.max(0,Math.min(y,6))},set x(v){y=v}})
f=s=>eval(s.replace(/./g,m=>`x${m}=1,`,y=1)+'"1N"[x]||x')
console.log(f("-++"))

Qwertiy
fuente
0

Retina, 65 bytes

^
1 N23456
+(` (.)?(\w*6)u
$1 $2
)`(.)? (\w*6)d
 $1$2
.* (.).*
$1

Uses u and d for up and down.

Try it online!

Explanation

This program works by keeping 1N23456 behind the sequence of instructions. It keeps track of the current gear by having a space behind it. Then it takes one instruction at a time until there's no more.

^
1 N23456

Start by putting 1 N23456 before the input. The space before N indicates that N is the current gear.


+(` (.)?(\w*6)u
$1 $2
)`(.)? (\w*6)d
 $1$2

These are two replacement stages, grouped together, and run until they stop changing the string:

 (.)?(\w*6)u
$1 $2

The first one handles shifting the gear up. It will look for any number of gears after the space, followed by a 6, then followed by u (u indicates the instruction to gear shift up). If there were characters before the 6, it swaps the space with the character immediately after it, deletes the u, and leaves the rest of the string intact. Since the 6 is mandatory in the match, it will only swap the space with any character before the 6. It will never swap with the 6.

(.)? (\w*6)d
 $1$2

The second stage handles gear shifting down, and works similarly. It looks optionally for a character before the space, then some other gears after ending in 6, followed by d. It swaps the space with the character before it, deletes the d, and leaves the rest intact. If the space was at the start of the string, there was no match for a character before the space, so no swap occurs.


.* (.).*
$1

After neither of the above replacements can be done anymore, all gear shifts have been completed. The line is cleared of everything except the gear immediately after the space. This is the final gear.

Business Cat
fuente
0

Powershell, 112 87 85 bytes

$i=1;switch([char[]]$args[0]){'^'{if(5-gt$i){$i++}}'v'{if(1-le$i){$i--}}}'1N2345'[$i]

ungolfed

$i=1;                                # index which gear we are in
switch([char[]]$args[0]){            # loop over all elements using a switch
  '^'{if(5-gt$i){$i++}}             # if there is a ^ and we are not in sixth yet, shift up
  'v'{if(1-le$i){$i--}}             # if there is a v and we are not in first, shift down
}
'1N2345'[$i]                         # print the output

saved 25 bytes by reading the powershell codegolf tips

saved 2 bytes by flipping the gt/le operators

Bjorn Molenmaker
fuente
0

Perl 6, 144 bytes

my enum C <1 N 2 3 4 5 6>;my $n=prompt("");my $p=1;for split("",$n) ->$l {$l eq "u" && $p < 6 ?? ++$p !! 0;$l eq"d"&&$p>0 ?? --$p!!0};say C($p);

Works as it should, i believe. Improvements are welcome. First time using Perl for anything, but i loved the thought of the language, so i had to try.

Håvard Nygård
fuente
0

Clojure, 74 bytes

#((vec "1N23456")(reduce(fn[c s](max 0(min 6((if(= s \^)inc dec)c))))1 %))

Folds over the shift string, maintaining an index as the accumulator. Each iteration it either increases or decreases the index, then clamps it to the range 0-6. Finally, a string holding the gears is indexed and returned.

Returns a Clojure character representing the current gear. Gear 1 is returned as \1, and gear 'N' is returned as \N.

Pre-golfed explanation. Follow the numbers, since it doesn't read well top-down.

; Expects ^ for shift-up, and V (or anything else) for shift down
; Returns a character representing the current gear
(defn shift [shift-str]
  ((vec "1N23456") ; 4. Then index the gear list with the calculated index, and return
   (reduce (fn [current-gear s] ; 1. Fold over the shift symbols
             (max 0 (min 6 ; 3. Clamp it to the range 0-6 so we don't overflow
                      ((if (= s \^) inc dec) ; 2. If the shift is up, increase, else decrease
                       current-gear))))
           1
           shift-str)))
Carcigenicate
fuente
0

Python 3, 67 63 bytes

k=1
for i in input():k+=[k<6,-(k>0)][i<'1']
print('1N23456'[k])

Pretty straightforward solution.

-4 bytes thanks to @ovs!

HyperNeutrino
fuente