0

The idea was to create a function that takes a string of some integers, text that can also include symbols like ',. etc. -If there is numbers in a string, return string -The first and last letter in a word should be untouched. Scramble only other letter.

  • If we have a "'" symbol, don't scramble it.

The problem is that I expect to print out as in the want section, but getting another result . For example: instead of a -> aa , metatr -> metater etc. I use seed = 100

Function to tokenize:

import "regexp"

func tokenize(text string) []string {
    re := regexp.MustCompile(`[A-Za-z0-9']+|[':;?().,!\\ ]`)
    return re.FindAllString(text, -1)
}

Scramble code

import (
    "math/rand"
    "strconv"
)

func scramble(text string, seed int64) string {
    rand.Seed(seed)
    slicy := tokenize(text)
    var str string = ""
    for a := 0; a < len(slicy); a++ {

        _, err := strconv.Atoi(slicy[a])
        if err != nil {

            var shufle []byte
            for i := 1; i < len(slicy[a])-1; i++ {
                shufle = append(shufle, slicy[a][i])
            }

            if slicy[a] != " " && slicy[a] != "." && slicy[a] != "," && slicy[a] != "(" && slicy[a] != ")" {
                new_length := 0
                for d := 0; d < len(shufle); d++ {
                    if string(shufle[d]) == "'" {
                        new_length = d - 1
                    }
                }
                if new_length != 0 {
                    for l := 0; l < new_length-1; l++ {
                        m := l + 1
                        shufle[l], shufle[m] = shufle[m], shufle[l]
                    }
                } else {
                    rand.Shuffle(len(shufle), func(k, j int) {

                        shufle[k], shufle[j] = shufle[j], shufle[k]
                    })
                }

                var scrambled_list []byte
                scrambled_list = append(scrambled_list, slicy[a][0])
                for d := 0; d < len(shufle); d++ {
                    scrambled_list = append(scrambled_list, shufle[d])
                }
                scrambled_list = append(scrambled_list, slicy[a][len(slicy[a])-1])

                str = str + string(scrambled_list)
            } else {
                switch slicy[a] {
                case " ":
                    str += " "
                case ".":
                    str += "."
                case "(":
                    str += "("
                case ")":
                    str += ")"
                case ",":
                    str += ","
                default:

                }
            }
        } else {
            return text
        }
    }

    return str
}

When i test it, i fails on:

Input:

"it doesn't matter in what order the letters in a word are, the only important thing is that the first and last letter be at the right place."

Want:

 "it deson't metatr in waht oredr the lettres in a wrod are, the only inmproatt thing is taht the frist and last letetr be at the right plcae."

What I get:

"it deson't metater in waht odrer the leretts in aa wrod are, the olny imtoaprnt thnig is that the fisrt and last leettr be at the right place."

  • Can you please clearly state what is the problem with the result you get? I think I get it but it is not clear – NuLo Sep 18 '21 at 10:59
  • @NuLo the problem is that I expect to print out as in the want section, but getting another result . For example: instead of a -> aa , metatr -> metater etc. I use seed = 100 – Slim Mathew Sep 18 '21 at 11:07
  • That was what I undertood, can you please edit and put that in the question. Since it is a random process the results should be different and those problems are not clear for an outsider – NuLo Sep 18 '21 at 11:09
  • 1
    please include reproducible example. https://play.golang.org/p/QSj_1YbFL29 –  Sep 18 '21 at 12:31

1 Answers1

2

this is an alternative solution given my understanding of OP requirements.

Wthiin a seneetnc, if it is nto a nburem, scrmaebl eahc wosrd, btu levae itnact teohs cceahrsrta "'".,()", the frtsi lrteet, and the ltsa ltreet.

It uses the bufio.Scanner configured to split the input by words using bufio.ScanWords.

When a word is found, if it is detected as a number it leaves it intact, otherwise, it checks for the length of the word, if it is greater than 2, then it shuffle the word.

To shuffle the word, it scans it by portion of text until ".,()'\"" using strings.IndexAny, each portion is then shuffled using rand.Shuffle.

package main

import (
    "bufio"
    "fmt"
    "math/rand"
    "strconv"
    "strings"
)

func main() {
    input := `Within a sentence, if it is not a number, scramble each words, but leave intact those characters "'\".,()", the first letter, and the last letter.`
    output := scramble(input, 100)
    fmt.Printf("%v\n", input)
    fmt.Printf("%v\n", output)
}

func scramble(text string, seed int64) (output string) {
    rand.Seed(seed)

    b := bufio.NewScanner(strings.NewReader(text))
    b.Split(bufio.ScanWords)

    for b.Scan() {
        w := b.Text()
        _, err := strconv.Atoi(w)
        if err == nil || len(w) < 2 {
            output += w
        } else {
            output += shuffleWord(w)
        }
        output += " "
    }
    return strings.TrimSuffix(output, " ")
}

func shuffleWord(input string) (output string) {
    if len(input) < 2 {
        output = input
        return
    }
    r := []rune(input)
    ln := len(r)
    for i := 1; i < ln-1; i++ {
        n := strings.IndexAny(input[i:], ".,()'\"")
        if n == -1 {
            n = ln - i
        }
        if n > 0 {
            rand.Shuffle(n, func(k, j int) {
                r[i+k], r[i+j] = r[i+j], r[i+k]
            })
            i += n - 1
        }
    }
    output = string(r)
    return
}

try it here