高尔夫文字成DNA


26

文字转DNA高尔夫

挑战

将输入转换为DNA输出。

算法

  • 将文本转换为ASCII码点(例如codegolf-> [99, 111, 100, 101, 103, 111, 108, 102]
  • 将ASCII码串在一起(例如99111100101103111108102
  • 转换为二进制(例如10100111111001101001011010001000011001101011011110000110010111111011000000110
  • 0s 填充到末尾以形成偶数个字符(例如101001111110011010010110100010000110011010110111100001100101111110110000001100
  • 更换00A01C10G,并11T(例如GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA
  • 输出量

测试用例

codegolf > GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA
ppcg > GGCTAATTGTCGCACTT
} > TTGG (padding)

技术指标

  • 这是
  • 您的程序必须在输入中接受空格。
  • 您的程序必须适用于codegolf

2
我认为您应该添加一个需要填充行为的测试用例。懒惰的选择将是}我所相信的TTGG
FryAmTheEggman'5

3
我们需要支持多少输入?99111100101103111108102例如大于uint-64,因此某些语言可能会遇到较大的转换。
AdmBorkBork,2016年

4
如果您想再次解码ASCII码,那不是将字符串串在一起的方式。
user253751 '16

我知道@immibis。
NoOneIsHere16年

Answers:


17

果冻15 13 字节

OVBs2UḄị“GCTA

在线尝试!验证所有测试用例

怎么运行的

OVBs2UḄị“GCTA    Main link. Argument: s (string)

O                Ordinal; replace each character with its code point.
 V               Eval. This converts the list to a string before evaluating, so it
                 returns the integer that results of concatenating all the digits.
  B              Binary; convert from integer to base 2.
   s2            Split into chunks of length 2.
     U           Upend; reverse the digits of each chunk.
                 Reversing means that we would have to conditionally PREPEND a zero
                 to the last chunk, which makes no difference for base conversion.
      Ḅ          Unbinary; convert each chunk from base 2 to integer.
                 `UḄ' maps:
                     [0, 1   ] -> [1,    0] -> 2
                     [1, 0(?)] -> [0(?), 1] -> 1
                     [1, 1   ] -> [1,    1] -> 3
                     [0, 0(?)] -> [0(?), 0] -> 0
       ị“GCTA    Replace each number by the character at that index.
                 Indexing is 1-based, so the indices are [1, 2, 3, 0].

9

CJam,24个 23个字节

感谢Dennis以一种非常聪明的方式节省了1个字节。:)

l:isi2b2/Wf%2fb"AGCT"f=

在这里测试。

说明

规范的直接实施。唯一有趣的是填充到偶数个零(这实际上是丹尼斯的想法)。而不是按照通常的顺序对待每对数字,我们将第二位设为最高位。这就是说,以单个位结尾与向其添加零相同,这意味着我们根本不必附加零。

l          e# Read input.
:i         e# Convert to character codes.
si         e# Convert to flat string and back to integer.
2b         e# Convert to binary.
2/         e# Split into pairs.
Wf%        e# Reverse each pair.
2fb        e# Convert each pair back from binary, to get a value in [0 1 2 3].
"AGCT"f=   e# Select corresponding letter for each number.

我对CJam一无所知,但是为什么您需要颠倒每对?您不能直接将它们从二进制转换回吗?
价值墨水

@ KevinLau-notKenny反转每对可避免附加零以得到均匀的长度。在反向对中,您必须在前面加上零,这与基本转换无关紧要。
丹尼斯

好招!如果我考虑过这个窍门,它可能会在我自己的解决方案上节省大量的字节
Value Ink

6

Python 2中,109个 103字节

lambda s,j=''.join:j('ACGT'[int(j(t),2)]for t in
zip(*[iter(bin(int(j(`ord(c)`for c in s))*2)[2:])]*2))

Ideone上进行测试


4

Ruby,59个字节

$_='%b0'.%$_.bytes*''
gsub(/../){:ACGT[$&.hex%7]}
chomp'0'

完整程序。与-p标志一起运行。


您什至...我不明白
珍视墨水

4

Python 3,130个字节。

由于使用了vaultah,节省了2个字节。
感谢Kevin Lau节省了6个字节-不是Kenny。

我讨厌在python中转换成二进制有多难。

def f(x):c=bin(int(''.join(map(str,map(ord,x)))))[2:];return''.join('ACGT'[int(z+y,2)]for z,y in zip(*[iter(c+'0'*(len(c)%2))]*2))

测试用例:

assert f('codegolf') == 'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'
assert f('ppcg') == 'GGCTAATTGTCGCACTT'

看来您在第二个之后就有了另外一对括号''.join
Vault

@vaultah糟糕,是的,您是对的。
Morgan Thrapp '16

使用'ACGT'[int(z+y,2)]替代方法,直接从二进制转换而不是使用较长的字符串并从10开始转换。此外,不确定使用它将带来多少差异,而是使用re.sub替代凌乱的连接技巧?
价值墨水

@ KevinLau-notKenny Oooo,谢谢。我忘记了您可以使用指定基数int。我将调查re.sub,谢谢您的建议。
Morgan Thrapp '16

不错的方法,我想了(几乎)完全相同的代码,而无需查看您的代码。:)
Byte Commander

3

Ruby,80个字节

->s{s=s.bytes.join.to_i.to_s 2;s+=?0*(s.size%2)
s.gsub(/../){"ACGT"[$&.to_i 2]}}

问题就很简单了,可以从中挤出更多的字节:)
xsot

3

Mathematica,108个字节

{"A","C","G","T"}[[IntegerDigits[Mod[Floor@Log2@#,2,1]#&@FromDigits[""<>ToString/@ToCharacterCode@#],4]+1]]&

将字符串作为输入,并输出一个碱基列表。


3

Python 3,126个字节

lambda v:"".join(["ACGT"[int(x,2)]for x in map(''.join,zip(*[iter((bin(int("".join([str(ord(i))for i in v])))+"0")[2:])]*2))])

欢迎来到编程难题和代码高尔夫球!如果您想知道下降票,那就是发生了什么
丹尼斯

2

Pyth,25个字节

sm@"ACGT"id2Pc.B*4sjkCMQ2

在这里尝试!

说明

Martins CJam的答案中挖掘填充技巧。

sm @“ ACGT” id2Pc.B * 4sjkCMQ2#Q =输入

                     CMQ#将Q的每个字符映射到其字符代码
                  sjk#加入一个字符串并转换为整数
              .B * 4#与4乘以并转换为二进制
             c 2#分成对
            P#丢弃最后一对
 m#映射每对d
         id2#将对从二进制转换为十进制
  @“ ACGT”#使用结果^作为查找字符串的索引
s#将结果列表加入字符串中


2

Java,194个字节

String a(int[]a){String s="",r=s;for(int i:a)s+=i;s=new BigInteger(s).toString(2)+0;for(int i=0,y,n=48;i<(s.length()/2)*2;r+=s.charAt(i++)==n?y==n?'A':'G':y==n?'C':'T')y=s.charAt(i++);return r;}

不打高尔夫球

String a(int[] a) {
    String s = "", r = s;
    for (int i : a) s += i;
    s = new BigInteger(s).toString(2) + 0;
    for (int i = 0, y, n = 48; i < (s.length() / 2) * 2; 
        r += s.charAt(i++) == n 
                 ? y == n 
                 ? 'A' 
                 : 'G' 
                 : y == n 
                 ? 'C' 
                 : 'T')
        y = s.charAt(i++);
    return r;
}

注意

  • 输入是一个字符数组(应以字符串形式计数),参数是类型,int[]因为多数民众赞成在其中保存了一个字节char[]

输出量

Input:  codegolf
Output: GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA

Input:  .
Output: GTG

Input:  }
Output: TTGG

Input:  wow
Output: TGATAGTTGTGCTG

Input:  programming puzzles
Output: GTGTCAGAGTTGAAGGCCGTTCCGCAGTGCATTTGGCTCGTCTGGTGTCTACTAGCCTGCGAGAGGAGTTACTTTGGATCCTTGACTTGT

2

MATL,21字节

'CGTA'joV4Y2HZa2e!XB)

在线尝试!

说明

'CGTA'   % Push string to be indexed into
j        % Take input string
o        % Convert each char to its ASCII code
V        % Convert to string (*). Numbers are separated by spaces
4Y2      % Push the string '0123456789'
H        % Push number 2
Za       % Convert string (*) from base '0123456789' to base 2, ignoring spaces
2e       % Reshape into a 2-column matrix, padding with a trailing 0 if needed
!        % Transpose
XB       % Convert from binary to decimal
)        % Index into string with the DNA letters. Indexing is 1-based and modular

1

Pyth,23个字节

sm@"AGCT"i_d2c.BsjkCMQ2

在线尝试!

说明

Dennis的果冻答案中借用the

sm@"AGCT"i_d2c.BsjkCMQ2
                   CMQ   convert each character to its byte value
                sjk      convert to a string and then to integer
              .B         convert to binary
             c        2  chop into pairs
 m         d             for each pair:
          _                  reverse it
         i  2                convert from binary to integer
  @"AGCT"                    find its position in "AGCT"
s                        join the string

1

Groovy,114个字节

{s->'ACGT'[(new BigInteger(((Byte[])s).join())*2).toString(2).toList().collate(2)*.with{0.parseInt(it.join(),2)}]}

说明:

{s->
    'ACGT'[ //access character from string
        (new BigInteger( //create Big Integer from string
           ((Byte[])s).join() //split string to bytes and then join to string
        ) * 2) //multiply by 2 to add 0 at the end in binary
        .toString(2) //change to binary string
        .toList() //split to characters
        .collate(2) //group characters by two
        *.with{
            0.parseInt(it.join(),2) //join every group and parse to decimal
        }
     ]
}

好答案!能否请您添加说明?
NoOneIsHere

第一个版本无法正常工作,因为我忘了附加0。我对其进行了修复,然后减少了btw个字节。
KrzysztofAtłasik'5

1

朱莉娅0.4,77字节

s->replace(bin(BigInt(join(int(s)))),r"..?",t->"AGCT"[1+int("0b"reverse(t))])

此匿名函数将字符数组作为输入并返回一个字符串。

在线尝试!


1

Python 2.7,135个字节

def f(A):g=''.join;B=bin(int(g(map(str,map(ord,A)))))[2:];B+=len(B)%2*'0';return g('ACGT'[int(B[i:i+2],2)] for i in range(len(B))[::2])

取消高尔夫:

def f(A):
    g = ''.join
    B = bin(int(g(map(str,map(ord,A)))))[2:] # convert string input to binary
    B += len(B)%2 * '0' # add extra 0 if necessary
    return g('ACGT'[int(B[i:i+2],2)] for i in range(len(B))[::2]) # map every two characters into 'ACGT'

输出量

f('codegolf')
'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'

@DrGreenEg​​gsandHamDJ我g(...)在那儿有两次函数,所以我相信用替换它join会增加2个字节吗?
deustice

啊,我错过了。我的错!
DJMcMayhem

1

的Javascript ES7,105个 103字节

s=>((+[for(c of s)c.charCodeAt()].join``).toString(2)+'0').match(/../g).map(x=>"ACGT"['0b'+x-0]).join``

ES7部分就是该for(c of s)部分。

ES6版本,107个 105字节

s=>((+[...s].map(c=>c.charCodeAt()).join``).toString(2)+'0').match(/../g).map(x=>"ACGT"['0b'+x-0]).join``

非高尔夫代码

dna = (str)=>{
  var codes = +[for(c of str)c.charCodeAt()].join``;
  var binaries = (codes.toString(2)+'0').match(/../g);
  return binaries.map(x=>"ACGT"['0b'+x-0]).join``
}

这是我第一次尝试使用PPCG打高尔夫球,如果有问题,请随时纠正我。

感谢@AlexA的细微改进。


1
这是一个不错的第一场高尔夫球!由于该函数不是递归的,并且我们不需要命名函数,因此您应该能够删除f=,节省2个字节。:)
Alex A.

1

J,52个字节

 3 :'''ACGT''{~#._2,\#:".,&''x''":(,&:(":"0))/3&u:y'

用法:3 :'''ACGT''{~#._2,\#:".,&''x''":(,&:(":"0))/3&u:y' 'codegolf'==>GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA


1

普通Lisp(Lispworks),415字节

(defun f(s)(labels((p(e f)(concatenate'string e f)))(let((b"")(d""))(dotimes(i(length s))(setf b(p b(write-to-string(char-int(elt s i))))))(setf b(write-to-string(parse-integer b):base 2))(if(oddp #1=(length b))(setf b(p b"0")))(do((j 0(+ j 2)))((= j #1#)d)(let((c(subseq b j(+ j 2))))(cond((#2=string="00"c)(setf d(p d"A")))((#2#"01"c)(setf d(p d"C")))((#2#"10"c)(setf d(p d"G")))((#2#"11"c)(setf d(p d"T")))))))))

松散:

(defun f (s)
  (labels ((p (e f)
             (concatenate 'string e f)))
  (let ((b "") (d ""))
    (dotimes (i (length s))
      (setf b
            (p b
               (write-to-string
                (char-int (elt s i))))))
    (setf b (write-to-string (parse-integer b) :base 2))
    (if (oddp #1=(length b))
        (setf b (p b "0")))
      (do ((j 0 (+ j 2)))
          ((= j #1#) d)
        (let ((c (subseq b j (+ j 2))))
          (cond ((#2=string=  "00" c)
                 (setf d (p d "A")))
                ((#2# "01" c)
                 (setf d (p d "C")))
                ((#2# "10" c)
                 (setf d (p d "G")))
                ((#2# "11" c)
                 (setf d (p d "T")))))))))

用法:

CL-USER 2060 > (f "}")
"TTGG"

CL-USER 2061 > (f "golf")
"TAAAAATTATCCATAAATA"


0

Perl 6,57 +1(-p标志)= 58字节

$_=(+[~] .ords).base(2);s:g/..?/{<A G C T>[:2($/.flip)]}/

逐步说明:

-p标志使Perl 6解释器逐行运行代码,放入当前行$_,最后从放回$_

.ords-如果在句号之前没有任何内容,则调用方法$_ords方法以字符串形式返回代码点列表。

[~]- []是归约运算符,将其归约运算符存储在括号之间。在这种情况下,它~是字符串连接运算符。例如,[~] 1, 2, 3等效于1 ~ 2 ~ 3

+将其参数转换为数字,这base是必需的,因为方法仅针对整数定义。

.base(2) -将整数转换为以2为底的字符串

$_=-将结果分配给$_

s:g/..?/{...}/-这是一个正则表达式,用于替换任何(:g,全局模式)regex实例..?(一个或两个字符)。第二个参数是替换模式,在这种情况下,该替换模式在代码中使用(在Perl 6中,字符串和替换模式中的大括号作为代码执行)。

$/ -正则表达式匹配变量

.flip-反转字符串。它将$/(正则表达式匹配对象)隐式转换为字符串。这是因为单个字符1应扩展为10,而不是01。由于该翻转,数组中元素的顺序反转了G和C。

:2(...) -将以2为基的字符串解析为整数。

<A G C T> -四个元素的数组。

...[...] -数组访问运算符。

这意味着什么?程序获取字符串中所有代码点的列表,将它们连接在一起,将其转换为基数2。然后,根据数字的翻转表示,它将两个或一个字符的所有实例替换为字母A,G,C,T中的一个以二进制形式。


0

Hoon148138字节

|*
*
=+
(scan (reel +< |=({a/@ b/tape} (weld <a> b))) dem)
`tape`(flop (turn (rip 1 (mul - +((mod (met 0 -) 2)))) |=(@ (snag +< "ACGT"))))

“ abc”是原子的列表。将它们内插到字符串(<a>)中,同时将其折叠到列表中,然后将它们连接在一起成为新的字符串。用解析数字,++dem将其返回到原子。

将数字乘以(按位长度+ 1)%2进行填充。用于++rip将原子的每两个字节对分解为一个列表,映射到列表,并将该数字用作字符串“ ACGT”的索引。

> =a |*
  *
  =+
  (scan (reel +< |=({a/@ b/tape} (weld <a> b))) dem)
  `tape`(flop (turn (rip 1 (mul - +((mod (met 0 -) 2)))) |=(@ (snag +< "ACGT"))))
> (a "codegolf")
"GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA"
> (a "ppcg")
"GGCTAATTGTCGCACTT"
> (a "}")
"TTGG"
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.