不完全是罗马三元


23

给定整数n≥0,请使用数字139ABCDE…和1个字符的分隔符以非位置基3表示法将其输出。每个数字都是3的连续幂,并且分隔符左侧的数字被取反,例如 A931 | B →81-(1 + 3 + 9 + 27)→ 41。一个数字只能出现一次。

严格地,让一个数字的值为:

  • 如果数字是1、3或9,则为它的值
  • 27如果数字是 A
  • B.. 之前的数字值的3倍Z

您的输出应满足sum(右边|的数字值)-sum(左边的数字值|)== input

例子

input     output
----------------
0         |
1         |1
7         3|91
730       |D1
9999      FEDC|GA9

您可以使用其他非空格字符作为分隔符。还允许您没有分隔符,在这种情况下,最大的数字以正数开头。您不需要处理大于2 32 -1(PMIGDCBA9|RQNLH3)的任何东西。

您可以编写完整的程序或函数,并且可以在任何常用通道上提供输入和输出。

这是,因此答案越短越好!


2
(相关并不意味着重复,请冷静下来)
Leaky Nun

8
我是唯一一个不知道在这里问什么的人吗?
粗野的

3
@Shaggy将输入表示为3的幂与它们的负数之和。将负数放在a的左边,|将正数放在它的右边。
马丁·恩德

2
@KevinCruijssen“不,订单免费。” - OP
user202729

3
@ user202729啊,错过了那条评论。谢谢。这就是当规则出现在注释中而不是编辑到挑战中时会发生的情况。(FrownyFrog,您可以将规则添加到挑战中吗:定界符两侧的
任一顺序

Answers:


5

爪哇10,120个 113 112 109 107 102字节

n->{var r="|";for(char c=49;n++>0;c=(char)(c+=c>64?1:c*4%22%9),n/=3)r=n%3<1?c+r:n%3>1?r+c:r;return r;}

通过使用@Arnauld JavaScript(ES6)答案的一部分技巧-3字节,
i=0and 更改i++<1?49:i<3?51:i<4?57:i+61i=4and ++i>9?i+55:i>8?57:++i+43
-6个字节,直接通过@Arnauld来消除i

输出顺序:最高到最低,- |分隔符,最低到最高。

说明:

在线尝试。

n->{              // Method with integer parameter and String return-type
  var r="|";      //  Result-String, starting at the delimiter "|"
  for(char c=49;  //  Character, starting at '1'
      n++>0       //  Loop as long as `n` is larger than 0
                  //  Increasing it by 1 with `n++` at the start of every iteration
      ;           //    After every iteration:
       c=(char)(  //     Change character `c` to:
          c+=c>64?//      If the current `c` is an uppercase letter:
              1   //       Simpy go to the next letter using `c+1`
             :    //      Else:
              c*4%22%9),
                  //       Change '1' to '3', '3' to '9', or '9' to 'A' 
       n/=3)      //     Integer-divide `n` by 3
     r=           //     Change the result to:
       n%3<1?     //      If `n` modulo-3 is 0:
        c+r       //       Prepend the character to the result
       :n%3>1?    //      Else-if `n` modulo-3 is 2:
        r+c       //       Append the character to the result
       :          //      Else:
        r;        //       Leave `r` unchanged
   return r;}     //  Return the result-String

1
我认为这有效:103个字节
Arnauld

@Arnauld不错!并通过放入r循环主体再增加-1个字节。谢谢!
凯文·克鲁伊森

@Arnauld出于好奇,您对这最后两个魔术数字所使用的暴力破解者是什么样子(当您仍在使用时i,以及在您重新使用时c)?
凯文·克鲁伊森

1
我已经把它扔掉了...:-/但是这是最后一个。(效率很低,但是对于如此小的值也可以。)
Arnauld

(此外,我真的应该测试是否在代码中p=1并且是否不包含*1它-即使在那种情况下它不会导致更好的公式。)
Arnauld


5

JavaScript(ES6),82 80 79字节

输出为小写字母,希望可以。

f=(n,s=(k=4,'|'),c=++k>8?k.toString(36):++k-5)=>n?f(++n/3|0,[c+s,s,s+c][n%3]):s

在线尝试!

Leaky“ Ninja Master” Nun的答案类似,也基于xnor的答案

数字转换

我们从k = 4开始。当k小于9时,我们在每次迭代中将其递增两次,并减去5。之后,我们仅将其递增一次,然后将其转换为base-36。

  k  | ++k > 8       | k.toString(36) | ++k - 5  | result
-----+---------------+----------------+----------+--------
  4  | k=5  -> false |                | k=6 -> 1 | 1
  6  | k=7  -> false |                | k=8 -> 3 | 3
  8  | k=9  -> true  | '9'            |          | '9'
  9  | k=10 -> true  | 'a'            |          | 'a'
  10 | k=11 -> true  | 'b'            |          | 'b'
 ... | ...           | ...            | ...      | ...



2

Stax30 29 字节

£└≤☻╘pÿ╖╡A[ô%æτ⌐}►ºôßHl4⌡π%^ 

运行并调试

平衡三进制转换器中 Stax答案的端口。

说明

使用解压后的版本进行解释。

139$VA+cz{;3%+,^3/~;wY1|I@'|ay2|I@L
139$VA+c                               "139AB...Z", make a copy
        z                              Empty array to store the digits
          {         w                  Do the following until 0.
           ;3%+                           Append `b%3` to the digits
                                          Originally, `b` is the input
              ,^3/                        `b=(b+1)/3`
                  ~;                       Make a copy of `b` which is used as the condition for the loop

                     Y                 Save array of digits in `y` for later use
                      1|I              Find index of 1's
                         @             Find the characters in "139AB...Z" corresponding to those indices
                          '|           A bar
                            ay2|I@     Do the same for 2's
                                  L    Join the two strings and the bar and implicit output

1

C#.NET,103字节

n=>{var r="|";for(var c='1';n++>0;c=(char)(c>64?c+1:c+c*4%22%9),n/=3)r=n%3<1?c+r:n%3>1?r+c:r;return r;}

我的Java 10答案端口。如果可以使用直接端口(n->to 除外n=>),那么我将使用此多语言编辑Java答案。但是不幸的是,c+=在字符中或c=49在C#中是不可能的,因此这个松散的移植答案。

在线尝试。


1

Perl 5中 -p71 69个字节

不使用分隔符。负数和正数部分按“罗马顺序”(大数位在前)

#!/usr/bin/perl -p
$n=$_}{s/@{[$n++%3]}\K/]/,$n/=3,y/?-]/>-]/for($_=21)x31;y/>?@12/139/d

在线尝试!



1

J,129字节

f=:3 :0
a=.'139',u:65+i.26
s=.'|'while.y>0 do.if.1=c=.3|y do.s=.s,{.a end.y=.<.y%3
if.c=2 do.s=.s,~{.a 
y=.1+y end.a=.}.a end.s
)

在线尝试!

太长了,特别是对于J程序...

说明:

f =: 3 : 0
   a =. '139',u:65+i.26   NB. a list '139ABC...Z'
   s =. '|'               NB. initialize the list for the result  
   while. y>0 do.         NB. while the number is greater than 0
      c =. 3|y            NB. find the remainder (the number modulo 3)
      y =. <.y%3          NB. divide the number by 3 
      if. c = 1 do.       NB. if the remainder equals 1
         s =. s,{.a       NB. Append the current power of 3 to the result
      end.
      if. c = 2 do.       NB. if the remainder equals 2 
         s =. s,~{.a      NB. prepends the result with the current power of 3
         y =. 1+y         NB. and increase the number with 1
      end.
      a =. }.a            NB. next power of 3 
   end.
   s                      NB. return the result  
)

1

C int138123字节,long152131字节

我创建了两个版本,因为最大工作输入的挑战极限0x100000000似乎有些奇怪。一个版本使用32位整数(出于显而易见的原因,该限制失败),另一个版本使用64位(超出给定限制,但额外增加了14 8个字节)。

32位版本:

char b[22],*r=b;f(v,l)char*l;{v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}

64位版本:

char b[22],*r=b;f(long v,char*l){v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(long v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}

除了声明整数变量为long(Linux上为64位)之外,这是相同的。

非高尔夫long版本:

char buffer[22],*result=buffer;
f(long value,char*letter){
    if(value%3>1){
        *result++=*letter,value++;
    }
    if(value){
        f(value/3,letter+1);
    }
    if(value%3){
        *result++=*letter;
    }
}
g(long value){
    f(value,"139ABCDEFGHIJKLMNOPQR");
    *result=0;
    result=buffer;
}

如您所见,这通过递归体面的方式起作用:如果余数为1,则在递归调用之后将各个字符附加到输出字符串。如果余数为2,则在递归之前执行输出。在这种情况下,我还将值增加一以正确处理负数。这具有将余数更改为零的附加好处,使我可以将value%3if作为递归后的条件。

转换结果放入全局缓冲区。该g()包装具有零正确终止得到的字符串,并以重置工作result指针,它的启动(这也是如何g()“回报”的结果)。

long使用以下代码测试版本:

#include <stdio.h>

char b[22],*r=b;f(long v,char*l){v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(long v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}

void printConversion(long value) {
    g(value);
    printf("%ld: %s\n", value, r);
}

int main() {
    for(long i = 0; i <= 40; i++) {
        printConversion(i);
    }
    printConversion(0x7fffffff);
    printConversion(0xffffffffu);
    printConversion(0x100000000);
}

可能进行的但破坏性的打高尔夫球:

  • -4个字节:通过删除中的指针重置,使该功能一次生效g()

  • -5个字节:强制调用者执行字符串终止,在中返回不终止的字符串,在中终止buffer字符串result


1

木炭,36字节

NθF³⊞υ⟦⟧F⁺139α«⊞§υθι≔÷⊕θ³θ»F²«×|ι↑⊟υ

在线尝试!链接是详细版本的代码。说明:

Nθ

输入值。

F³⊞υ⟦⟧

将三个空列表推送到预定义的空列表。

F⁺139α«

循环浏览字符139和大写字母。

⊞§υθι

用值循环索引列表的列表,然后将当前字符推入该列表。

≔÷⊕θ³θ»

将值除以3,但先加1取整。

F²«×|ι

循环两次。第二次,打印|

↑⊟υ

每个循环我们从列表中弹出最后一个条目。第一次,这给我们提供了余数2(对应于平衡三进制数-1)的条目,而第二次,给了我们对应于平衡三进制数的条目1。生成的阵列通常可以垂直打印,但是向上旋转打印方向可以将其取消。



0

Perl 5中92 89个字节

受到java和python答案的启发。

sub n{($n,$r,$c,@a)=(@_,'|',1,3,9,'A'..'Z');$n?n(int++$n/3,($c.$r,$r,$r.$c)[$n%3],@a):$r}

在线尝试!

有一些空格:

sub n {
  ($n, $r, $c, @_) = (@_, "|", 1, 3, 9, 'A' .. 'Z');
  $n ? n( int++$n/3, ($c.$r, $r, $r.$c)[$n%3], @_)
     : $r
}

0

PHP,73字节

for(;0|$n=&$argn;$n/=3)${$n++%3}.=_139[++$i]?:chr(61+$i);echo${2},_,${1};

xnor的答案端口,53个字节

for(;0|$n=&$argn;$n/=3)$s="0+-"[$n++%3].$s;echo$s??0;

与管道一起运行-nr在线尝试它们

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.