Oldukça Değil Roma Üçlüsü


23

N = 0 olan bir tamsayı verilirse, rakamları 139ABCDE…ve 1 karakterli bir ayırıcı kullanarak onu konumsal olmayan bir taban-3 notasyonunda verin . Her hane ardışık 3'lük bir güçtür ve ayırıcının sol tarafındaki sayılar negatiftir , örneğin A931 | B → 81− (1 + 3 + 9 + 27) → 41 . Bir rakam yalnızca bir kez görünebilir.

Titizlikle, bir basamağın değeri şöyle olsun:

  • basamak 1, 3 veya 9 ise değeri
  • 27 ise, rakam A
  • Rakamın hemen önündeki değerin 3 katı B..Z

Çıktınız toplamı (sağdaki basamakların değeri)|| karşılamalı - toplam (soldaki basamakların değeri ) == giriş .

Örnekler

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

Ayırıcı olarak farklı bir boşluk olmayan karakter kullanabilirsiniz . Ayırıcınız olmamasına da izin verilir, bu durumda en büyük hane pozitif diziyi başlatır. 2 32 −1 ( PMIGDCBA9|RQNLH3) değerinden daha büyük herhangi bir işlem yapmanıza gerek yoktur .

Tam bir program veya fonksiyon yazabilirsiniz ve normal kanalların herhangi birinde giriş ve çıkış sağlanabilir.

Bu , bu yüzden cevap ne kadar kısa olursa o kadar iyi!


2
(ilgili kişi çift anlamına gelmez, sakinleşir)
Leaky Nun

8
Burada ne istendiğine dair hiçbir ipucu olmayan tek kişi ben miyim?
Shaggy

3
@Shaggy Girdiyi 3'lük güçlerin toplamı ve negatifleri olarak ifade edin. Negatifleri a |ile pozitifleri sola , sağına koyun.
Martin Ender

2
@KevinCruijssen "hayır, sipariş ücretsiz." - OP
kullanıcı202729

3
@ user202729 Ah, bu yorumu kaçırdım. Teşekkürler. Bu, kurallar meydan okumaya dahil olmak yerine yorumlarda olduğunda gerçekleşir. ( FrownyFrog , bu kuralı mücadeleye ekleyebilir misin: sınırlayıcının her iki tarafındaki bir düzen iyi mi?)
Kevin Cruijssen

Yanıtlar:


5

Java 10, 120 113 112 109 107 102 bayt

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

-3 hüner bir kısmını kullanarak, bayt @Arnauld sitesindeki JavaScript (ES6) yanıt ,
değişen i=0ve i++<1?49:i<3?51:i<4?57:i+61için i=4ve ++i>9?i+55:i>8?57:++i+43.
-6 bayt @Arnauld sayesinde doğrudan kurtularak i.

Çıktı sırası: En yüksek-en düşük, |-sınır, en düşük-en yüksek.

Açıklama:

Çevrimiçi deneyin.

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
Sanırım bu işe yarıyor: 103 bayt
Arnauld

@Arnauld Güzel olanı! Ve rdöngü gövdesine koyarak -1 bayt . Teşekkürler!
Kevin Cruijssen

@ Merak etme Meraktan yoksun olan kabadayılar bu son iki sihirli sayı için kullandığın gibi duruyor (hala kullandığında ive tekrar kullandığında c)?
Kevin Cruijssen

1
Çoktan atmıştım ...: - / Ama işte sonuncusu . (Çok verimsiz, ancak böyle küçük değerler için sorun yok.)
Arnauld

(Ayrıca, eğer kodun içinde olup olmadığını test etmeli p=1ve eklememeliyim *1- bu durumda daha iyi bir formüle yol
açmasa da


5

JavaScript (ES6), 82 80 79 bayt

Küçük harfle çıktılar, ki umarım iyi olmalı.

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

Çevrimiçi deneyin!

Benzer Çatlak "Ninja Usta" Nun cevabı ve ayrıca dayalı XNOR cevabı .

Basamak dönüşüm

K = 4 ile başlıyoruz . K 9'dan küçük olsa da , her yinelemede iki kere artırır ve 5'i çıkarırız . Ondan sonra, sadece bir kez arttırırız ve onu baz-36'ya çeviririz.

  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

Stax , 30 29 bayt

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

Koş ve hata ayıkla

Stax Ternary Converter'deki Stax cevabımın limanı .

açıklama

Açıklamak için paketlenmemiş sürümü kullanır.

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 bayt

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 cevabımın limanı . (Hariç doğrudan bir bağlantı noktası ise n->hiç n=>) mümkün olurdu, ben bu dili içine benim Java cevabını düzenlenmiş olurdu. Ancak ne yazık ki, c+=karakterler üzerinde veya c=49C # 'da mümkün olmadığından, bu açık kaynaklı cevap.

Çevrimiçi deneyin.


1

Perl 5 -p , 71 69 bayt

ayırıcı kullanmaz. Negatif ve pozitif kısımlar "roma sırasına" göre (ilk önce en büyük rakam)

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

Çevrimiçi deneyin!



1

J , 129 bayt

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
)

Çevrimiçi deneyin!

Çok uzun, özellikle bir J programı için ...

Açıklama:

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 int: 138 123 baytlong : 152 131 bayt

Bunun iki versiyonunu yarattım, zorlukların bir çalışma max girişi sınırlaması olarak 0x100000000 biraz garip görünüyordu. Bir sürüm 32 bit tamsayılarla çalışır (ki bu açık sebeplerden dolayı sınırı alamaz), diğer sürüm ise 64 bit ile çalışır (bu, belirtilen limitin ötesine geçen, 14 8 ekstra bayt pahasına ).

32 bit sürüm:

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 bit sürüm:

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

Bu, tamsayı değişkenini long(linux üzerinde 64 bit) olacağını bildirmesi dışında aynıdır .

Ungolfed longversiyonu:

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

Gördüğünüz gibi, özyinelemeli terbiyeli çalışır: Kalan 1 ise, ilgili karakter özyinelemeli çağrıdan sonra çıkış dizesine eklenir. Kalan 2 ise, çıkış özyinelemeden önce gerçekleştirilir. Bu durumda, negatif basamağı doğru işlemek için değeri bir artırırım. Bu beni kullanmak için izin sıfıra kalan değişen yararı vardır value%3post-yineleme için bir koşul olarak.

Dönüşümün sonucu global tamponun içine yerleştirilir. g()Sarıcı sıfır işin doğru sonuç dizesi sonlandırma ve sıfırlamak zorundaresult (aynı zamanda nasıl olduğu onun başlangıç işaretçi g()"döner" sonuç).

longSürümü bu kodla test edin :

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

Muhtemel, fakat yıkıcı golf:

  • -4 bayt: sıfırlama işaretçisini kaldırarak işlevi tek seferde yapın g().

  • -5 bayt: arayanı dizenin sonlandırmasını, dizenin sonlandırılmadan geri döndürülmesi ve dizenin buffersonunun gerçekleştirilmesi için zorlar result.


1

Kömür , 36 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Açıklama:

Nθ

Değeri giriniz.

F³⊞υ⟦⟧

Önceden tanımlanmış boş listeye üç boş liste itin.

F⁺139α«

Karakterleri 139ve büyük harfli alfabeyi dolaşın.

⊞§υθι

Değerli listelerin listesini periyodik olarak indeksleyin ve mevcut karakteri ona itin.

≔÷⊕θ³θ»

Değeri 3'e bölün, ancak önce 1 ekleyerek onu yuvarlayın.

F²«×|ι

İki kez döngü. İkinci kez, a |.

↑⊟υ

Her döngü biz listeden son girişi açar; bu ilk kez bize kalanı 2(dengeli bir üçlü basamağa karşılık gelir -1) olan girişleri verirken, ikinci kez bize dengeli bir üçlü basamağa karşılık gelen girişleri verir 1. Ortaya çıkan dizi normalde dikey olarak yazdırılır, ancak yazdırma yönünü yukarı doğru döndürmek bunu iptal eder.



0

Perl 5 , 92 89 bayt

Java ve python cevaplarından esinlenilmiştir.

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}

Çevrimiçi deneyin!

Biraz beyaz boşlukla:

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.