摩托车齿轮检查器!


36

你们中有些人可能熟悉摩托车的换档方式。但是对于那些不喜欢的人,看起来像这样

6

5

4

3

2

ñ

1个

现在,我想知道在执行几次上,下变速操作后我所处的档位。该程序应从中立开始。

输入样例:

V^^

样本输出:

2

如您所见,我从N降档至1,然后升至2档。

这是代码高尔夫球。以字节为单位的最短答案将获胜。

注意:输入可以是任何2个字符。可以是U和D表示上下,也可以是字符串。您不能超越1挡或6挡。如果您排在第六名并再次升档,它将保持在第六名。祝好运!


5
下次,请将您的挑战发布到沙盒上以获取反馈,然后再将其发布到主
站点

1
@seshoumara仅有的两个要求是必须是字符串,并且只能输入2个字符。因此可以使用换行符作为字符。但是如果您出于其他原因使用它,我也不介意。看看您的想法会很有趣。但请简短说明为什么要这样做。GL!
Martijn Vissers

4
可惜的是,这并不能说明1到N之间的半步转换。不仅可以走2 N 1 N 2 3,而且可以走2 1 N 2 3,这很精巧
Cort Ammon

2
我同意@CortAmmon-1和2之间只有一个移位。中立位置是半个移位。
Džuris

2
并非所有的摩托车都这样移动。大多数无离合器摩托车的换挡速度为N-1-2-3-4(在某些非常古老的车辆上为N-1-2-3)。他们没有齿轮5或6,而是使用圆形齿轮,即当齿轮为4时,增大齿轮将使其缠绕到
N。– phuclv

Answers:


15

JavaScript(ES6),49 48 47 46字节

期望:

  • 1 下来
  • 7 为了
f=([c,...s],g=2)=>c?f(s,g-c&7||g):'1N'[--g]||g

格式化和评论

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

齿轮映射如下:

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)

这使我们可以轻松地通过以下方法检查当前齿轮的有效性:

(g & 7) != 0

演示版


7

05AB1E22 20字节

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

在线尝试!

说明

Î                      # 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

6

MATL,32 28 23字节

@Luis节省了5个字节

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

该解决方案'2'用于升档和'0'降档。

MATL Online上尝试

说明

'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

@Lifeless更新后有解释
Suever

非常好!请问为什么字符串是234561N而不是1n23456或65432n1?我也发现了一个缺陷!如果继续升档,它应该保持在6档,但它会返回N
Martijn Vissers

1
真好!不知道累积限制的技巧
B. Mehta

1
@ B.Mehta我也不是!路易斯推荐了它
Suever

1
@ B.Mehta另外,请随时加入我们的MATL聊天室
Suever

6

V20,15个字节

:sil!î¬61énÀxVp

在线尝试!

输入是h(向上)和l(向下)字符的字符串。

感谢@nmjcman节省了5个字节,并教会了我一些我不了解的vim功能!

如果我们可以假设输入永远不会超出范围,那么它就是9个字节:

¬61énÀxVp

但是很遗憾,这是不允许的。

说明:

: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

2
另外,在线尝试!V压缩。这很酷。
nmjcman101

实际上,我认为这行不通,因为超过或低于1/6会破坏宏:/
nmjcman101 '17

为什么不允许9个字节的答案?
艾伯特·伦肖

@AlbertRenshaw如果您尝试换档超过1档或6档,它将失败。例如,在线尝试!应该输出n,而不是1
DJMcMayhem

哦,我明白了,我认为输入法始终有效,您的意思是不移位的字符。即使无效,仍然是一个很酷的答案
Albert Renshaw

6

Java 7中,106个 105 103字节

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);}

说明:

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
}

测试代码:

在这里尝试。

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"));
  }
}

输出:

2
6
1
N

5

Haskell,59 53 51字节

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

用途0用于下来2最多。用法示例:

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

感谢@xnor腾出6个字节!另外,事实证明,我不需要函数名称或括号,因此又是2个字节。


如果将输入字符设为0和2,则可以执行read[c]-2
xnor

欢迎来到PPCG!匿名函数也很好,因此您不需要g=
Laikoni '17

@Laikoni我必须将其包装在括号中,对吗?那不会改变字节数,所以我想我会离开,g=因为它更清楚
user1472751


4

JavaScript(ES6),48 58字节

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

用法

将其分配给一个函数,然后调用它。输入是一个字符串,其中包含一个1升档和0一个降档。

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"

f(0)返回1而不是N ...如果您从6上移或从1下移,则代码返回undef
fəˈnɛtɪk

接得好。固定为两个字节的成本
路加福音

不起作用,例如f("001")哪个输入应返回N(减速比为1,减速比保持为1,减速比为N)
Emigna

不应该循环。它应该留在6,如果在1 6和住院升档,如果从1。此外,降档,它仍然给民主基金,如果你从1个调档
fənɛtɪk

4

PHP 7.1,71个字节

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

$g从-1 转换为5,对第一档使用负弦偏移。
使用运行-nr,提供移位字符串作为命令行参数。


4

果冻17 14字节

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

用途6最多和0换下来。

在线尝试!

怎么运行的

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.

2

Ruby,58个字节

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

预期输入为“ v”表示降档,“ ^”表示升档


2

处理JS(已修改)121字节

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]);

不打高尔夫球

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]);

在线尝试!

我很了解PJ,所以我去了。唯一的问题是我使用的版本类型非常严格。我不能遗漏括号和许多其他技巧。这很简单。输入应该进入变量a,并采用小写形式u d。程序将循环直到到达字符串末尾,并在每次迭代时检查其是否为au或d。如果是这样,它将不会尝试“转移”到可以转移的位置。最后,我打印结果!


我认为,如果您的版本允许三元运算符,则您也许可以以更短的方式重写ifs。
Bojidar Marinov

The input should go into the variable a使用硬编码输入不是默认的输入方法,请参见此处
Laikoni '17

@Laikoni真的吗?真傻。我没有更好的办法。如果我必须重做,那将要长〜100个字节
Christopher

您不能简单地将代码包装在一个函数中吗?例如。void f(String[] a){...}几乎没有100个字节。
Laikoni '17

@Laikoni在可汗学院ProcessingJS中,它是 JS,因此没有String或void。但是您是对的,函数会更短
Kritixi Lithos

2

k,25个字节

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

它以字符串形式输入,并[用于降档和]升档,因为它们位置便利。

"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

例子:

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

2

GNU sed89 87 +1(r标志)= 88字节

由于sed没有整数类型或算术运算,因此只能通过使用正则表达式来得出解决方案。

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

通过沿每个仅包含单元格的无包装胶带将x输入指针向左(用于Up)或向右(用于D自己)滑动指针来工作65432N1。最后的答案是指针左侧单元格中的值。

示例运行:在线尝试!

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

说明:

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)

这是76个字节,但以一元输出。
莱利

@Riley Unary,当然!好吧,您的解决方案有所不同,所以为什么不发布它!
seshoumara

你的给了我灵感。我想如果您愿意,我会让您使用它。
莱利

@Riley然后,我将用您的版本做一个单独的部分,并向您表示感谢。
seshoumara

我会发表自己的文章:)
Riley

2

GNU sed76 73字节

包括+1的 -r

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

输出是一元的,除了中性,后者仍然是N(请参阅此共识)。

在线尝试!

这基本上是一元的递增和递减,然后将1转换为N,将0转换为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

我认为,您的sed版本可以缩短4个字节,如果您将1as用作起始值as N,则不作1s/$/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字节

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

取消高尔夫:

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

用法示例(在Rebol控制台中):

>> print f "DUU"         
2

>> print f "DDDUU"
2

>> print f "UUUUUUUUU"  
6

>> print f "UUUUUUUUUD"
5

2

> <>,35个字节

一段热情的代码,鼓励您超越速度限制。

接受代码模3为0和2的任意两个输入,例如02
为了增加鱼腥味,我建议使用<>

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

说明:

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

您可以在这里尝试


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)

根据输入来移动字符串的索引并打印相关字符。


1

Pyth,32个字节

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

使用空格和换行符上下。

说明

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

几乎可以肯定,有一种更好的方法来进行增量和输出。


1

CJam24 22字节

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

用途(用于下来)最多。

在线尝试!

说明

"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

1

批处理,144字节

@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

接受STDIN上的输入,0用于进入较低档位并6进入较高档位。选择这些数字是为了轻松忽略当前齿轮。最终,如果1然后N打印齿轮,则0转换为1并打印齿轮。


0

的Javascript ES6非严格,136 120个字符

136个字符 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个字符 -+

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("-++"))


0

视网膜,65字节

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

用途ud上和下。

在线尝试!

说明

该程序通过保留1N23456指令序列来工作。通过在其后面留有空间,它可以跟踪当前齿轮。然后一次只需要一条指令,直到没有更多指令为止。

^
1 N23456

首先放在1 N23456输入之前。之前的空格N表示N当前档位。


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

这是两个替换阶段,分组在一起,并运行直到它们停止更改字符串为止:

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

第一个负责将齿轮升档。它将在空格后查找任意数量的档,然后是6,然后是uu指示加速的指令)。如果在6之前有字符,它将立即与它后面的字符交换空格,删除u,并使字符串的其余部分保持不变。由于6在比赛中必须使用,因此只会将空格与之前的任何字符交换6。它永远不会与交换6

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

第二阶段处理换低档,并且工作类似。它可以选择在空格前寻找一个字符,然后在结尾处查找其他齿轮6,然后是d。它将空格与前面的字符交换,删除d,其余部分保持不变。如果空格位于字符串的开头,则空格前的字符不匹配,因此不会发生交换。


.* (.).*
$1

在以上两种替换方法均无法完成后,所有换档均已完成。除空格后的齿轮外,生产线上的所有物品都清除了。这是最后的装备。


0

Powershell,112 87 85字节

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

不打高尔夫球

$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

通过阅读Powershell CodeGolf技巧节省了25个字节

通过翻转gt / le运算符节省了2个字节


0

Perl 6,144字节

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);

我相信,它应能正常工作。欢迎改进。第一次使用Perl做任何事情,但是我喜欢这种语言的想法,所以我不得不尝试。


0

Clojure,74个字节

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

折叠移位字符串,并保持索引作为累加器。每次迭代都会增加或减少索引,然后将其限制在0-6范围内。最后,索引并返回一个包含齿轮的字符串。

返回表示当前齿轮的Clojure字符。齿轮1返回为\1,齿轮'N'返回为\N

预先解释。请按照数字进行操作,因为自上而下的阅读效果不佳。

; 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)))

0

Python 3,67 63字节

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

非常简单的解决方案。

-4个字节感谢@ovs!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.