FizBuzz를 항상 설치할 필요 없음

22660 단어 Go퍼즐fizzbuzztech

대희리의 제목.


무엇이 소양입니까?


직역상수이 바로'직치'인 것도 평소 귀에 거슬리는 단어다.
간단하고 알기 쉽게 표현하면 코드 내에서 직사된 수치와 문자열 등의 상수다.
모두 표기는 자신의 값을 직접 나타내기 때문에'직선값'이다.

피즈버즈가 뭐예요?


FizzBuzz는 언어 게임의 일종이다.숫자를 세면서 특정한 규칙으로 다른 단어로 바꾸다.
프로그래밍의 세계에서 Hello world 등과 병렬된 학습 장르가 사랑받고 있다.
# input
 1  2  3  4  5  6  7  8  9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 ...

# output
 1  2 Fizz  4 Buzz Fizz  7  8 Fizz Buzz
11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz
Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz
31 ...
의 기본 규칙은 다음과 같다.
  • 1부터 숫자를 하나씩 늘리면서 출력
  • 숫자가 3으로 나누어졌을 때 숫자 대신'Fizz'를 출력
  • 숫자를 5로 나누면 숫자 대신 "Buzz"출력
  • 숫자를 3과 5로 나누면 숫자 대신'Fizz Buzz'를 출력
  • 간단하게 실시하면 다음과 같다.
    FizBuzz 설치 예제(유능)
    fizzbuzz_with_literal.go
    package main
    
    import "fmt"
    
    func main() {
      for n := 1; n <= 31; n++ {
        put_fizzbuzz_or_num(n)
        put_delimiter(n)
      }
      fmt.Println()
    }
    
    func put_fizzbuzz_or_num(n int) {
      switch {
      case can_div(n, 15):
        fmt.Print("FizzBuzz")
      case can_div(n, 3):
        fmt.Print("Fizz")
      case can_div(n, 5):
        fmt.Print("Buzz")
      default:
        fmt.Print(n)
      }
    }
    
    func put_delimiter(n int) {
      switch {
      case can_div(n, 10):
        fmt.Println()
      default:
        fmt.Print(" ")
      }
    }
    
    func can_div(n int, d int) bool {
      return n%d == 0
    }
    
    https://play.golang.org/p/Vut8z6f4JY2

    소양이 없어도 피즈버즈를 쓸 수 있나요?


    네, 쓸 수 있어요.
    언어 방법을 활용하여 필요한 수치와 문자열을 동적으로 생성하면 된다.
    FizBuzz 설치 예제(상수 없음)
    fizzbuzz_without_literal.go
    package main
    
    import (
      "fmt"
      "reflect"
    )
    
    type Fizz int
    type Buzz int
    
    var fizz Fizz
    var buzz Buzz
    
    const (
      N0  = iota         // 0: ゼロ
      N1                 // 1: 順列の開始番号
      N3  = N1 + N1 + N1 // 3: Fizz出力判定用
      N5  = N3 + N1 + N1 // 5: Buzz出力判定用
      N10 = N5 + N5      // 10: 改行出力判定用
      N31 = N10*N3 + N1  // 31: 順列の終了番号
      N32 = N31 + N1     // 32: 半角空白のASCIIコード
    )
    
    func main() {
      fizzbuzz()
    }
    
    func fizzbuzz() {
      FIZZ := reflect.TypeOf(fizz).Name() // Fizz: 文字列
      BUZZ := reflect.TypeOf(buzz).Name() // Buzz: 文字列
      LINE_FEED := fmt.Sprintln()         // (LF): 改行
      WHITE_SPACE := string(rune(N32))    // (SP): 半角空白
      for n := N1; n <= N31; n++ {
        ifput(n%N3 == N0, FIZZ)
        ifput(n%N5 == N0, BUZZ)
        ifput(n%N3 != N0 && n%N5 != 0, fmt.Sprint(n))
        ifput(n%N10 == 0, LINE_FEED)
        ifput(n%N10 != 0, WHITE_SPACE)
      }
      fmt.Println()
    }
    
    func ifput(eval bool, put string) {
      if eval {
        fmt.Print(put)
      }
    }
    
    https://play.golang.org/p/6VPVAHbAdIn

    수치 생성 시도


    이번에 생성해야 할 수치는 다음과 같다.
  • 배열의 시작과 끝의 번호를 입력(1,31 ※ 끝의 번호는 임의로)
  • 제거되었는지 판단하는 제수(3,5,15=3*5)
  • 모두 자연수이기 때문에 정수 1을 준비할 수 있다면 이를 바탕으로 연산을 생성할 수 있다.

    수법1 더하기 연산자를 사용하여 0에서 1을 생성합니다.


    대부분의 언어에서 정수 변수의 정의되지 않은 초기 값은 0입니다.
    마찬가지로 대다수 언어는 정수형의 가산자가 있다.
    따라서 하나의 덧셈 연산자를 사용하여 1을 만들고 덧셈으로 각 수치를 생성한다.
    gen-num-from-no1.go
    package main
    
    import "fmt"
    
    func main() {
      var N1 int // default: 0
      N1++
      var N2 = N1 + N1
      var N3 = N2 + N1
      var N5 = N2 + N3
      var N15 = N3 * N5
      var N31 = N15 * N2 + N1
      fmt.Println(N1, N2, N3, N5, N15, N31)
      // stdout: 1 2 3 5 15 31
    }
    
    https://play.golang.org/p/WZ1Jie4mIQY

    수법수조의 길이에서 숫자가 생기다


    대부분의 언어는 함수가 그룹 요소의 수량을 되돌려줍니다.
    원소 1의 배열 길이를 계산하고 1을 만든 다음 연산을 통해 칸 수치를 생성한다.
    같은 덧셈에는 기능이 없기 때문에 이번에는 비트 연산을 해 보았다.
    gen-num-from-len.go
    package main
    
    import "fmt"
    
    func main() {
      var N1 int
      N1 = len([]int{N1})
      var N2 = N1 << N1
      var N3 = N2 | N1
      var N5 = N2 << N1 | N1
      var N15 = N3 << N2 | N3
      var N31 = N15 << N1 | N1
      fmt.Println(N1, N2, N3, N5, N15, N31)
      // stdout: 1 2 3 5 15 31
    }
    
    https://play.golang.org/p/xI9UZowuXVA

    문자열 생성


    수법숫자에서 문자 생성


    이번에 생성해야 할 문자열은'Fizz'와'Buzz'두 개다.
    둘 다ASCII에 포함된 문자의 조합입니다.
    ASCII는 7자리의 이진수로 0~127의 정수로 영숫자와 기호의 문자 코드를 분배한다.
    그리고 대부분의 언어는 ASCII를 수치와 문자로 처리할 수 있는 표준 함수를 제공합니다.
    즉, 다음 절차에서는 "Fizz"및 "Buzz"를 준비할 수 있습니다.
  • ASCII 문자에 대응하는 수치를 준비합니다(전절 "수치 생성 시도"참조)
  • 언어의 표준 함수를 사용하여 ASCII 수치 표현에서 문자 표현으로 변환
  • 각 문자를 병합하여 필요한 문자열을 만듭니다
  • .

    수법반사를 통해 문자열 추출


    일부 언어에서는 리플렉스라고 불리는 메커니즘을 제공했다.
    반사를 사용하면 프로그램의 구조를 얻을 수 있다.
    예를 들어 문자열로 처리할 수 있는 다음 형식의 이름을 얻을 수 있습니다.
    gen-str-with-reflection.go
    package main
    
    import (
      "fmt"
      "reflect"
    )
    
    type FizzBuzz *interface{}
    
    func main() {
      var v FizzBuzz
      fmt.Println(reflect.TypeOf(v).Name())
      // stdout: FizzBuzz
    }
    
    https://play.golang.org/p/3OP5QPrPbvz

    최후


    평소 가독성 관점에서 추천하지 않는 퍼즐식 구현도 흥미롭다.
    여러분들도 각자 좋아하는 언어 해볼까요?
    아마도 어떤 새로운 발견과 발견이 있을 것이다.

    좋은 웹페이지 즐겨찾기