当前位置: 首页 > 知识库问答 >
问题:

围棋练习之旅#23:rot13Reader

公良向阳
2023-03-14

我正在尝试解决围棋练习之旅,读者:

下面是我的解决方案:

package main

import (
    "io"
    "os"
    "strings"
)

type rot13Reader struct {
    r io.Reader
}

func rot13(x byte) byte {
    switch {
    case x >= 65 && x <= 77:
        fallthrough
    case x >= 97 && x <= 109:
        x = x + 13
    case x >= 78 && x <= 90:
        fallthrough
    case x >= 110 && x >= 122:
        x = x - 13
    }
    return x
}

func (r13 *rot13Reader) Read(b []byte) (int, error) {
    n, err := r13.r.Read(b)
    for i := 0; i <= n; i++ {
        b[i] = rot13(b[i])
    }
    return n, err
}

func main() {
    s := strings.NewReader("Lbh penpxrq gur pbqr!")
    r := rot13Reader{s}
    io.Copy(os.Stdout, &r)
}

它返回You prnpxrq tur poqr!,这意味着只有第一个单词lbh penpxrq gur pbqr!是裂开的。我怎样才能破解整个句子?

共有3个答案

唐海阳
2023-03-14

我更喜欢直接操作Rot13函数中的整数

package main

import (
    "io"
    "os"
    "strings"
)

type rot13Reader struct {
    r io.Reader
}

const a int = int('a')
const z int = int('z')

const A int = int('A')
const Z int = int('Z')

func rot13(b int) int {

    isLower := b >= a && b <= z
    isUpper := b >= A && b <= Z

    if isLower {
        return a + ((b - a + 13) % 26)
    }

    if isUpper {
        return A + ((b - A + 13) % 26)
    }

    return b
}

func (rot *rot13Reader) Read(b []byte) (int, error) {
    n, err := rot.r.Read(b)
    if err == io.EOF {
        return 0, err
    }

    for x := range b {
        b[x] = byte(rot13(int(b[x])))
    }
    return n, err
}

func main() {
    s := strings.NewReader("Lbh penpxrq gur pbqr!")
    r := rot13Reader{s}
    io.Copy(os.Stdout, &r)
}
金高飞
2023-03-14

您也可以使用:

func rot13(x byte) byte {
    input := []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
    output := []byte("NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm")
    match := bytes.Index(input, []byte{x})
    if match == -1 {
        return x
    }
    return output[match]
}
甄阿苏
2023-03-14

编辑:

基本上你的解决方案是好的,工作,你只是输入错误的1个字符:

case x >= 110 && x >= 122:

将其更改为:

case x >= 110 && x <= 122:

您的输入和输出:

Lbh penpxrq gur pbqr!
You prnpxrq tur poqr!

每个单词都有变化。问题不在于只读取和解码第一个单词,而在于解码算法。

在ROT13中,如果移位超出了字母范围,您必须从字母表的开头(或结尾)开始。例如,将'N'移位为'Z'1,因此它成为'A',第一个字母。看到这个简单的字符映射:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm

所以你应该做的是在移位13后,如果字母超出了字母表,移位26(英语字母表中的字母数量),这具有预期的效果(在最后一个字母之后,你继续从第一个字母开始)。

一个示例解决方案:

func rot13(x byte) byte {
    capital := x >= 'A' && x <= 'Z'
    if !capital && (x < 'a' || x > 'z') {
        return x // Not a letter
    }

    x += 13
    if capital && x > 'Z' || !capital && x > 'z' {
        x -= 26
    }
    return x
}

其输出:

You cracked the code!

在运动场上试试看。

 类似资料:
  • 我正在进行围棋之旅,我觉得除了并发性之外,我对这门语言有很好的理解。 幻灯片10是一个练习,要求读者并行化一个网络爬虫(并使其不覆盖重复,但我还没有做到。) 以下是我到目前为止的情况: 我的问题是,在哪里我把调用。 如果我在方法中的某个地方放置了,那么程序最终会从一个派生的goroutine写入一个闭合通道,因为对的调用将在派生的goroutine执行之前返回。 如果我省略了对的调用,正如我所演示

  • 问题内容: 我正在经历“ A Go of Go”,并且一直在编辑大多数课程,以确保我完全理解它们。我对以下练习的答案有疑问: https : //tour.golang.org/concurrency/10,可在此处找到: https //github.com/golang/tour/blob/master/solutions/ webcrawler.go 我对以下部分有疑问: 从通道添加和删除t

  • 这是一个围棋学习免费软件。 本软件具有人机对局、双人对局、对局演示、对局打谱等功能,可选择2-19路棋盘对局,目前已有三步推算的棋力,可作为围棋初学者的辅助学习工具,也可作为围棋爱好者的辅助研究工具。 本软件采用易语言编写!易语言官方网址: http://www.dywt.com.cn http://www.eyuyan.com 版权所有(C) 2008-2009 梁远海 E-Mail: nply

  • 我们将研究的最后一个数据结构称为三叉搜索树(TSTree),它可以在一组字符串中快速查找字符串。它类似于BSTree,但是它有三个子节点,而不是两个,每个子节点只是一个字符而不是整个字符串。在BSTree中,左子节点和右子节点是树的“小于”和“大于”的分支。在TSTree中,左子节点,中子节点和右子节点是“小于”,“等于”和“大于”的分支。这可以让你选取一个字符串,将其分解成字符,然后遍历TSTr

  • 本文向大家介绍开启BootStrap学习之旅,包括了开启BootStrap学习之旅的使用技巧和注意事项,需要的朋友参考一下 本文总结了Bootstrap之所以广泛流传的11大原因。如果你还没有使用Twitter Bootstrap,建议你去了解一下。我也是最近才有所发现的,不过有更好的消息,在前两天微软发布的VS2013正式版中,也已经将BootStrap3.0的版本加入了额,连微软都看到boot

  • 这个练习是一个脑筋急转弯,我会向你介绍最著名的C语言黑魔法之一,叫做“达夫设备”,以“发明者”汤姆·达夫的名字命名。这一强大(或邪恶?)的代码中,几乎你学过的任何东西都被包装在一个小的结构中。弄清它的工作机制也是一个好玩的谜题。 注 C的一部分乐趣来源于这种神奇的黑魔法,但这也是使C难以使用的地方。你最好能够了解这些技巧,因为他会带给你关于C语言和你计算机的深入理解。但是,你应该永远都不要使用它们