隔行扫描


34

您面临的挑战是编写一个程序或函数,当给定两个相等长度的字符串时,该程序或函数将交换所有其他字符并以任一顺序输出/返回结果字符串。

例子

"Hello," "world!" --> "Hollo!" "werld,"
"code" "golf" --> "codf" "gole"
"happy" "angry" --> "hnpry" "aagpy"
"qwerty" "dvorak" --> "qvertk" "dworay"
"1, 2, 3" "a, b, c" --> "1, b, 3" "a, 2, c"
"3.141592653589" "2.718281828459" --> "3.111291623489" "2.748582858559"
"DJMcMayhem" "trichoplax" --> "DrMcMoylex" "tJichapham"
"Doorknob" "Downgoat" --> "Doonkoot" "Dowrgnab"
"Halloween" "Challenge" --> "Hhlloeegn" "Caallwnee"

规则

  • 字符串将仅包含ASCII字符(32-126)。
  • 字符串将始终具有相同的长度,并且永远不会为空。
  • 您可以接受任何适当格式的输入:单独的参数,数组中的项,以一个或多个换行符分隔,甚至是串联的。唯一的限制是一个字符串必须在另一个字符串之前完整出现(例如a1\nb2\nc3for "abc", "123"无效)。
  • 输出可以是任意顺序(即,您可以从第一个或第二个字符开始交换),并且可以采用上述任何有效格式。(2个项目的数组,由换行符分隔,串联等)

计分

这是,因此每种语言的最短代码(以字节为单位)获胜。


11
为+1 DrMcMoylex。:D
DJMcMayhem

3
“ Dowrgnab”字谜转换为“ Downgrab”(͡°͜ʖ°°)
Mama Fun

您应该明确指出“按任何顺序”规则意味着交换可以从第一个字符或第二个字符开始。
DLosc '16

@DrMcMoylex以代码为例,高尔夫示例。如果从第二个字符开始交换,则得到:c o d f,g o l e。从第一个字符开始:g o lec o d f。
DLosc '16

Answers:


14

Haskell,37个字节

l=(,):flip(,):l
(unzip.).zipWith3($)l

压缩两个字符串,交替交换字符,然后解压缩它们。

37字节的递归替代方案:

(a:b)?(c:d)=a:d?b
e?_=e
a%b=(a?b,b?a)

9

Python,具有I / O高尔夫功能的 42个字节

def f(a,b):a[1::2],b[1::2]=b[1::2],a[1::2]

交换两个列表中的所有其他字符。将两个字符列表作为输入,并通过对其进行修改来输出。

l=list('cat')
m=list('dog')    
print l,m

def f(a,b):a[1::2],b[1::2]=b[1::2],a[1::2]

f(l,m)
print l,m

['c', 'a', 't'] ['d', 'o', 'g']
['c', 'o', 't'] ['d', 'a', 'g']

1
那很聪明。您是否认为输入/输出格式过于灵活?
ETHproductions

@ETHproductions不确定,列表可能比字符串更容易处理,这可能主要是特定于Python的。
xnor

8

VIM,18,17个字节

qqyljvPkvPll@qq@q

在线尝试!

由于向后兼容,因此使用V解释器。输入格式如下:

string1
string2

说明:

 qq                 " Start recording in register 'q'
   yl               " Yank one letter
     j              " Move down a row
      vP            " Swap the yanked letter and the letter under the cursor
        k           " Move back up a row
         vP         " Swap the yanked letter and the letter under the cursor
           ll       " Move two letters to the right. This will throw an error once we're done
             @q     " Call macro 'q' recursively
               q    " Stop recording.
                @q  " Start the recursive loop

x代替,yl然后用jus P代替Second 切两个字母vPlqqxjvPkPll@qq@q
Hauleth '16

@lukasz我最初曾尝试过,但是由于任何原因,它运行了太多次,并且在不应该交换最后一个字母的情况下使用。我会进一步研究
DJMcMayhem


1
@ŁukaszNiemier该链接与我发布的代码相同。你按下[save]按钮了吗?无论哪种方式,它都不适合我。真正的原因是因为当您x在该行上的最后一个字符时,它将光标移至左侧,从而弄乱了交换位置。
DJMcMayhem

6

Haskell,41个字节

(a:b)#(c:d)=(a,c):d#b
_#_=[]
(unzip.).(#)

返回带有字符串的对。用法示例:( (unzip.).(#) ) "Hello," "world!"-> ("Hollo!","werld,")

简单的递归方法:将每个字符串的第一个字符作为一对,并在交换(其余)字符串的情况下追加递归调用。unzip从配对列表中制作一对列表。


6

05AB1E11 10字节

øvyNFÀ}})ø

在线尝试!

说明

输入= ["code", "golf"]用作示例。

ø             # zip strings into list of pairs
              # STACK: ['cg', 'oo', 'dl', 'ef']
 vy           # for each pair
   NFÀ        # rotate left index times
      }}      # end-if, end-loop
              # STACK: 'cg, 'oo', 'dl', 'fe'
        )ø    # wrap in list and zip
              # OUTPUT: ['codf', 'gole']

5

Perl,48个字节

字节数包括47个字节的代码和-p标志。

say<>=~s%.\K(.)%"s/.{$-[0]}\\K(.)/$1/;\$1"%geer

使用-p-E标志运行。期望每个字符串在不同的行上:

perl -pE 'say<>=~s%.\K(.)%"s/.{$-[0]}\\K(.)/$1/;\$1"%geer' <<< "Hello
World"

说明

-p:捕获输入$_并在最后打印。(获取并打印第一个字符串)
<>:获取输入行。(以获取第二个字符串)。
=~:将正则表达式应用到<>s%%%geer,其中感谢r返回修改后的字符串(然后打印感谢say)。
regex:
.\K(.)找到两个字符,并用此代码的评估结果替换第二个字符"s/.{$-[0]}\\K(.)/$1/;\$1"
第一部分,s/.{$-[0]}\\K(.)/$1/将regex应用于$_.{$-[0]}跳过第一个字符,使其到达与外部regex相同的位置(因为$-[0]包含第一个捕获组的索引,因此在这种情况下,要替换的字符的索引),然后我们使用(.)并将其替换为外部正则表达式($1)的字符。然后我们添加$1,结果"s/.{$-[0]}\\K(.)/$1/;\$1"是在内部正则表达式中捕获的字符。
您可能已经注意到,$1在两个字符串中都引用了我们要替换的字符(所以有两个不同的字符),因此我们使用/eeregex的修饰符,该修饰符对regex的右侧进行两次评估:第一个将只替换$1不是的之前没有\


5

Python,55个字节

lambda a,b:[(-~len(a)/2*s)[::len(a)+1]for s in a+b,b+a]

切片!

58个字节:

def f(a,b):n=len(a);print[(s*n)[:n*n:n+1]for s in a+b,b+a]

64个字节:

f=lambda a,b,s='',t='':a and f(b[1:],a[1:],s+a[0],t+b[0])or[s,t]

递归地将两个字符串的字符累积到s和中t,并在最后输出它们对。交替是通过在每个递归调用中切换输入字符串来完成的。输出以空格分隔的字符串的长度相同:

lambda a,b,s='',t=' ':a and f(b[1:],a[1:],s+a[0],t+b[0])or s+t

这几乎击败了一种不同的递归策略,即从两个字符串中分别取字符,并将两个可能的字符串中的每个字符串作为第一个。(65字节)

g=lambda a,b:a and a[0]+g(b[1:],a[1:])
lambda a,b:(g(a,b),g(b,a))

4

MATL11 10 9 8字节

感谢ETHproductions 1个字节的折扣!

"@X@YS&h

输入是一个包含两个字符串的2D数组,例如:['Halloween'; 'Challenge']。输出字符串的顺序相反。

在线尝试!

说明

        % Input 2D array implicitly
"       % For each column
  @     %   Push current column
  X@    %   Push iteration index, starting at 1
  YS    %   Circularly shift the column by that amount
  &h    %   Concatenate horizontally with (concatenated) previous columns
        % End implicitly
        % Display implicitly

旧版本:9个字节

tZyP:1&YS

说明

        % Take input implicitly
t       % Duplicate 
        % STACK: ['Halloween'; 'Challenge'], ['Halloween'; 'Challenge']
Zy      % Size
        % STACK: ['Halloween'; 'Challenge'], [2 9]
P       % Flip array
        % STACK: ['Halloween'; 'Challenge'], [9 2]
:       % Range. Uses first element of the array as input
        % STACK: ['Halloween'; 'Challenge'], [1 2 3 4 5 6 7 8 9]
1&YS    % Circularly shift each column by those amounts respectively
        % STACK: [Caallwnee';'Hhlloeegn']
        % Display implicitly

@ETHproductions是的!谢谢!
路易斯·门多

4

果冻,5 个字节

żṚż¥/

输入是单独的参数,输出是串联的。

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

怎么运行的

żṚż¥/  Main link. Left argument: s (string). Right argument: t (string)

ż      Zipwith; yield the array of pairs of corresponding characters of s and t.
   ¥   Combine the two links to the left into a dyadic chain:
 Ṛ         Reverse the chain's left argument.
  ż        Zip the result with the chain's right argument.
    /  Reduce the return value of the initial ż by the quicklink Ṛż¥.


3

V,12个字节

lòyljvPkvPll

在线尝试!

没什么有趣的,只是我的vim答案的直接移植,因此我可以与(但不能击败)05AB1E竞争。


3

Pyke,9个字节

,Fo2%I_(,

在这里尝试!

          - o = 0
,         -   transpose(input)
 F     (  -  for i in ^:
  o2%     -    (o++ %2)
     I_   -   if ^: i = reverse(i)
        , - transpose(^)

3

JavaScript(ES6),51 54

编辑保存的3个字节thx @Neil

具有数组输入/输出的功能

p=>p.map((w,i)=>w.replace(/./g,(c,j)=>p[i+j&1][j]))

我更喜欢这一点,但它是55(输入中包含2个字符串,输出中包含数组)

(a,b)=>[...a].reduce(([p,q],c,i)=>[q+c,p+b[i]],['',''])

测试

f=
p=>p.map((w,i)=>w.replace(/./g,(c,j)=>p[i+j&1][j]))

function go() {
  var a=A.value, b=B.value
  if (a.length == b.length)
    O.textContent = f([a,b]).join('\n')
  else
    O.textContent = '- different length -'
    
}

go()
<input id=A value='Hello,'><input id=B value='world!'>
<button onclick='go()'>go</button><pre id=O></pre>


replace为您节省3个字节:p=>p.map((w,i)=>w.replace(/./g,(c,j)=>a[i+j&1][j]))
尼尔

2

Pyth,8个字节

C.e_FbkC

在线尝试:演示

转置单词,反转每对字母的“当前索引”-次,再次转置。


2

JavaScript(ES6),55个字节

f=([c,...s],[d,...t],o="",p="")=>c?f(t,s,o+c,p+d):[o,p]

我想使用regexp替换替换字符做一些聪明的事,但是最终占用了67 57个字节:

a=>a.map((s,i)=>a[+!i].replace(/.(.?)/g,(_,c,j)=>s[j]+c))

真好 我有f=([a,...A],[b,...B])=>a?[a+f(B,A)[0],b+f(A,B)[0]]:[""]相同的长度。
ETHproductions

我希望能做得更好,但没有办法,少做一件事。发布非递归答案的时间
edc65 '16

@ edc65使用的好主意map,它使我的正则表达式答案减少了10个字节。仍然太久了。
尼尔

2

Perl,40个字节

包括+1的 -n

将字符串作为STDIN上的行

interlace.pl
hello
world
^D

interlace.pl

#!/usr/bin/perl -n
s/./${1&$.+pos}[pos]=$&/seg}{print@0,@1

2

Java中,132个 103 100字节

感谢Kevin Cruijssen建议返回数组(除其他改进外)并节省29个字节!还有3字节的OlivierGrégoire!

char[]c(char[]s,int l){for(int o=l;o-->0;)if(o%2>0){char t=s[o];s[o]=s[l+o+1];s[l+o+1]=t;}return s;}

这样称呼:

public static void main(String[] args) {
    System.out.println(c("Hello,world!".toCharArray(), 5)); // 5 is the length of each "String"
}

输出:

Hollo,werld!

利用这样的事实,即输入基本上可以以任何方式设置格式(在这种情况下,是一个用逗号分隔的字符串的单个char数组),并且输出规则也很宽松。


嗨,您已经准备好了原始输入格式。您还可以打高尔夫球:char[]c(char[]s,int l){for(int o=l,t;o-->0;)if(l%2>0){t=s[l];s[l]=s[l+o+1];s[l+o+1]=(char)t;}return s;}103字节),返回输出而不是直接打印输出。示例性输入:System.out.println(c("Hello,world!".toCharArray(), 5));; 输出示例:Hollo,werld!
凯文·克鲁伊森

的确如此,出于某种原因,我没有考虑仅返回char数组。那很棒!
Hypino '16

结果应该是Hollo!werld,,不是Hollo,werld!(标点符号不正确)。相信这可以固定的5.6而不是输入值
奥利弗格雷

既然您转换tchar,为什么不直接在for循环中将其声明为char?您可以节省一些字节。
奥利维尔·格雷戈尔

不幸的是,您不能在for循环初始化器中声明char,但是您启发了我检查一下,单独声明char是否比强制转换短,并且确实是1字节。
Hypino

1

C,124字节

main(c,v)char**v;{char a[99],b[99];for(c=0;v[1][c]^0;++c){a[c]=v[1+c%2][c];b[c]=v[2-c%2][c];}a[c]=0;b[c]=0;puts(a);puts(b);}

致电:

program.exe string1 string2

字符串长度限制为98个字符。



1

球拍208字节

(let((sl string->list)(ls list->string)(r reverse))(let p((s(sl s))(t(sl t))(u'())(v'())(g #t))(if(null? s)
(list(ls(r u))(ls(r v)))(p(cdr s)(cdr t)(cons(car(if g s t))u)(cons(car(if g t s))v)(if g #f #t)))))

取消高尔夫:

(define (f s t)
  (let ((sl string->list)                ; create short names of fns
        (ls list->string)
        (r reverse))
    (let loop ((s (sl s))                ; convert string to lists
               (t (sl t))
               (u '())                   ; create empty new lists
               (v '())
               (g #t))                   ; a boolean flag
      (if (null? s)                      ; if done, return new lists converted back to strings
          (list (ls (r u))
                (ls (r v)))
          (loop (rest s)
                (rest t)                 ; keep adding chars to new lists alternately
                (cons (first (if g s t)) u) 
                (cons (first (if g t s)) v)
                (if g #f #t))            ; alternate the boolean flag
          ))))

测试:

(f "abcdef" "123456")

输出:

'("a2c4e6" "1b3d5f")

以上是递归版本。

迭代版本:

(let*((sl string->list)(ls list->string)(r reverse)(s(sl s))(t(sl t))(l'())(k'())(p(λ(a b g)(set! l(cons(if g a b)l))
(set! k(cons(if g b a)k)))))(for((i s)(j t)(n(in-naturals)))(p i j(if(= 0(modulo n 2)) #t #f)))(list(ls(r l))(ls(r k))))

取消高尔夫:

(define (f s t)
  (let* ((sl string->list)              ; create short form of fn names
         (ls list->string)
         (r reverse)

         (s (sl s))                     ; convert strings to lists
         (t (sl t))

         (l '())                        ; create empty lists for new sequences
         (k '())

         (p (λ(a b g)                   ; fn to add chars to one or other list
              (set! l (cons (if g a b) l))
              (set! k (cons (if g b a) k)))))

    (for ((i s)(j t)(n (in-naturals)))  ; loop with both strings
          (p i j                        ; add to new lists alternately
             (if (= 0 (modulo n 2)) #t #f)))

    (list (ls (r l))                  ; convert reversed lists to strings
          (ls (r k)))))

1

PowerShell v2 +,82字节

param($a,$b)$i=0;[char[]]$a|%{$c+=($_,$b[$i])[$i%2];$d+=($b[$i],$_)[$i++%2]};$c;$d

还在打高尔夫球...不。如果不像其他答案一样使用正则表达式,似乎就无法做到这一点(复制算法中的嘘声)。

因此,我们将$aand $b作为字符串,将index设置$i0,转换$achar-array,然后通过loop发送|%{...}。每次迭代,我们都将其串接在一个数组选择上$c$d通过建立索引来进行索引(即,它来回交替)。然后,我们离开$c,并$d在管道上,并通过隐性输出Write-Output通常发生在程序完成。


1

Lithp,120个字符(-v1标志为+3)

为了便于阅读,将行分成两部分:

#P::((invoke P "map" (js-bridge #W,I::(replace W (regex "." "g")
     (js-bridge #C,J::(index (index P (& (+ I J) 1)) J))))))

需要-v1标志run.js由于某些功能尚未成为标准库的一部分,因此。

用法示例:

(
    (def f #P::((invoke P "map" (js-bridge #W,I::(replace W (regex "." "g")
                (js-bridge #C,J::(index (index P (& (+ I J) 1)) J)))))))
    (print (f (list "Hello," "world!")))
)

我没有在标准库上花费足够的时间来进行此类重点介绍。必须使用js-bridge/1两次和长正则表达式形式,以及使用invoke/*所有,这使得该过程比需要的时间长得多。

我认为,是时候在我的标准库上工作了。


1

PHP,79字节

for(;$i<=strlen(($a=$argv)[1]);$y.=$a[2-$i%2][$i++])echo$a[1+$i%2][+$i]??" $y";

先前版本PHP,82字节

for(;$i<strlen(($a=$argv)[1]);$y.=$a[2-$i%2][$i++])$x.=$a[1+$i%2][$i];echo"$x $y";

for(...)echo$a[1+$i%2][$i];echo" $y";(-2)
泰特斯

Titus的注释的建立for(;$i<=strlen(($a=$argv)[1]);$y.=$a[2-$i%2][$i++])echo$a[1+$i%2][$i]??" $y";是另外的-2,尽管它需要php 7
user59178

@ user59178不错,但你需要1个字节以上
约尔格Hülsermann

你呢?它对我Notice: String offset cast occurred in Command line code on line 1
有用

@ user59178是打印的第一个单词的第一个字母
约尔格Hülsermann

1

C,54 52字节

f(char*a,char*b,char*c){while(*c++=*a++,*c++=*b++);}

假设输出 c已经具有所需的长度。

用法:

main(){
 char a[]="123456";
 char b[]="abcdef";
 char c[sizeof(a)+sizeof(b)-1];
 f(a,b,c);
 puts(c);

}

如果您坚持创建输出,那么这里是一个91字节的解决方案:

char*g(char*a,char*b){char*c=malloc(2*strlen(a)),*d=c;while(*c++=*a++,*c++=*b++);return d;}

用法:

main(){
 char a[]="123456";
 char b[]="abcdef";
 puts(g(a,b));
}

0

C,150字节

我使用了头文件的典型省略以及main()的return type和return语句。它发出警告,但编译没有问题。我还使用了特定于GCC的技巧,该技巧允许使用变量表达式声明数组。

该程序需要命令行中的字符串,因此,该程序应使用来运行./a.out string1 string2

main(int a,char**v){int x=strlen(v[1]);char s[x],t[x],c;strcpy(s,v[1]);strcpy(t,v[2]);for(a=0;a<x;++a)if(a%2)c=s[a],s[a]=t[a],t[a]=c;puts(s),puts(t);}

或更清晰地说,

main(int a,char**v){
    int x=strlen(v[1]);
    char s[x],t[x],c;
    strcpy(s,v[1]);strcpy(t,v[2]);
    for(a=0;a<x;++a)
        if(a%2)c=s[a],s[a]=t[a],t[a]=c;
    puts(s),puts(t);
}

0

Mathematica,51个字节

将输入作为两个字符数组的数组,输出格式相同。该函数仅使用(mod 2)操作来构造新数组。

Table[#[[Mod[j+i,2]+1,j]],{i,2},{j,Length@#[[1]]}]&

0

QBasic 4.5,172字节

哎呀,这让Q'Basic感到痛苦...

DEFSTR A-D:INPUT A,B
IF LEN(A)MOD 2=1 THEN A=A+" ":B=B+" "
FOR x=1 TO LEN(A) STEP 2
C=C+MID$(A,x,1)+MID$(B,x+1,1):D=D+MID$(B,x,1)+MID$(A,x+1,1):NEXT:?RTRIM$(C),RTRIM$(D)

有趣的事实:使用DEFSTR节省的字节多于成本,因为现在我可以使用A代替a$


0

QBIC,112字节

QBIC可以简化许多QBasic样板,但MID$由于QBIC缺少子字符串功能,因此仍需要在QBasic中完成主机。不过,还是为我节省了60个字节。

;;_LA|~a%2=1|A=A+@ | B=B+C][1,a,2|X=X+$MID$(A$,b,1)+MID$(B$,b+1,1):Y$=Y$+MID$(B$,b,1)+MID$(A$,b+1,1)|]?_tX|,_tY|

MIND$=> MIN$在文本中。
并不是说查理

0

Java,68个字节

(a,b)->{for(int i=a.length;--i>0;){char t=a[--i];a[i]=b[i];b[i]=t;}}

取消测试

import java.util.Arrays;
import java.util.Collection;
import java.util.function.BiConsumer;

public class Main {

  static BiConsumer<char[], char[]> func = (left, right) -> {
      for (int i = left.length; --i > 0;) {
        char temp = left[--i];
        left[i] = right[i];
        right[i] = temp;
      }
    };

  public static void main(String[] args) {
    test("Hello,","world!", "Hollo!", "werld,");
    test("code", "golf", "codf", "gole");
    test("happy", "angry", "hnpry", "aagpy");
  }

  private static void test(String left, String right, String x, String y) {
    char[] leftChars = left.toCharArray();
    char[] rightChars = right.toCharArray();
    func.accept(leftChars, rightChars);
    Collection mixed = Arrays.asList(new String(leftChars), new String(rightChars));
    if (mixed.containsAll(Arrays.asList(x, y))) {
      System.out.println("OK");
    } else {
      System.out.printf("NOK: %s, %s -> %s%n", left, right, mixed);
    }
  }
}

0

APL,12

{↓(⍳⍴⊃⍵)⊖↑⍵}

说明:{...}定义一个函数,⍵是正确的参数。汇整(↑)从两个字符串中创建一个矩阵,然后将每列(⊖)旋转n次,其中n是括号(⍳⍴⊃⍵)中的部分。定义为第一个参数长度的iota。(例如:length = 5 ==> 1 2 3 4 5)。因此,第一列旋转一次,第二列旋转两次(回到原始位置),第三列旋转三次,依此类推...

tryapl.org上尝试

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.