[TIL] 2023-05-30

Melon Coder·2023년 6월 7일
0

TIL

목록 보기
43/50
post-thumbnail

Today I Learned


[Solidity]

오늘은 Quiz_8 풀이와 Quiz_9를 새로 풀었고, ERC-20, 721, 1155에 대해서 배워보았다.


Quiz_8 풀이

[문제]

로또 프로그램을 만드려고 합니다. 숫자와 문자는 각각 4개 2개를 뽑습니다.
6개가 맞으면 1이더, 5개의 숫자가 순서와 함께 맞으면 0.75이더,
4개가 맞으면 0.25이더, 3개가 맞으면 0.1이더 2개 이하는 상금이 없습니다.
참가 금액은 0.05이더이다.
기준 숫자 : 1,2,3,4,A,B
기준 숫자 설정 기능 : 5개의 사람이 임의적으로 4개의 숫자와 2개의 문자를 넣음.
5명이 넣은 숫자들의 중앙값과 알파벳 순으로 따졌을 때 가장 가운데 문자로 설정
예) 숫자들의 중앙값 : 1,3,6,8,9 -> 6 // 2,3,4,8,9 -> 4
예) 문자들의 중앙값 : a,b,e,h,l -> e // a,h,i,q,z -> i

강사님께서 문제 풀이하실 때는 3가지 방법으로 풀이를 공유해주셨다.

<1단계>

  1. 먼저 기준 숫자에 대한 배열을 각각 숫자[1,2,3,4], 문자[A, B]로 만든다.
uint[] numbers = [1,2,3,4];
string[] letters = ["a", "b"];

  1. 로또를 입력하고 개수를 맞추어 상금을 얻는 함수(setLotto, getPrize), 같은 숫자가 몇개인지 출력하는 함수(isSameNumber), 같은 문자가 몇개인지 출력하는 함수(isSameLetter), 문자가 같은 지 비교하는 함수(letterCompare)를 각각 만들어준다.

    *여기서 중요한 점은 상금을 얻는 함수(getPrize)private 으로 하고, 숫자/문자 배열을 입력받을 때 memory에 저장하는 것이 아닌 calldata에 저장해준다.(값이 바뀌지 않기 때문에)

<2단계>

  1. 기준 숫자에 대한 배열을 string[] 으로 통합하여(숫자+문자 -> 문자형) 만들어준다.
  2. address형 변수 owner를 만들어주고 constructor를 통해 owner를 msg.sender로 정해준다.
  3. <1단계>와 다른 점은 문자형 배열로 통합하였기 때문에 isSameLetter로만 비교하여 상금을 얻는다.

<3단계> (로또 번호 설정 기능 추가)

  1. 기준 숫자 배열의 크기를 6으로 지정하여 선언해준다.
string[6] targetLetters;
  1. 입력받은 문자형 배열에 대해서 bytes1 로 된 배열로 새로 생성한다.(new)
    function stringArrayToBytes1Array(string[] memory _a) public pure returns(bytes1[] memory) {
        uint _n = _a.length;
        bytes1[] memory _b = new bytes1[](_n);
        for(uint i=0; i<_n;i++) {
            _b[i] = abi.encodePacked(_a[i])[0];
        }
        return _b;
    }
  1. 입력받은 bytes1 크기의 두 바이트형 변수에 대해서 평균을 구하는 함수를 만든다. (배열의 길이가 짝수일 때 중앙값이 두 개 이기 때문에)
  2. 중앙값을 구하는 함수를 만든다. (for문을 통해 배열을 정렬하고 중앙값을 구함)
  3. 나머지는 1,2 단계와 같다.

Quiz_9

[문제]

흔히들 비밀번호 만들 때 대소문자 숫자가 각각 1개씩은 포함되어 있어야 한다 등의 조건이 붙는 경우가 있습니다. 그러한 조건을 구현하세요.

입력값을 받으면 그 입력값 안에 대문자, 소문자 그리고 숫자가 최소한 1개씩은 포함되어 있는지 여부를 알려주는 함수를 구현하세요.

나의 문제 풀이

  1. 먼저 string으로 입력을 받고 대문자, 소문자, 숫자의 존재 여부에 대해 bool타입으로 변환해주는 것을 생각하여 boolean형 변수 isUpperCase, isLowerCase, isNumber를 선언해줬다. (기본값은 false)
  2. 대문자, 소문자, 숫자에 대한 아스키코드 값을 아는 것이 중요했다. 그래서 각각에 대한 아스키코드의 존재 여부를 통해 return값을 반환해주었다.
contract QUIZ9 {
    function setPW(string memory _pw) public pure returns(bool) {
        bool isUpperCase;
        bool isLowerCase;
        bool isNumber;

        for (uint i=0; i < bytes(_pw).length; i++) {
            bytes1 bytes_pw = bytes(_pw)[i];

            if (uint8(bytes_pw) <= 39 && uint8(bytes_pw) >= 30) {
                isNumber = true;
            } else if (uint8(bytes_pw) <= 122 && uint8(bytes_pw) >= 97) {
                isLowerCase = true;
            } else if (uint8(bytes_pw) <= 90 && uint8(bytes_pw) >= 65) {
                isUpperCase = true;
            }
        }
        if (isUpperCase && isNumber && isLowerCase) {
            return true;
        } else {
            return false;
        }

    }

0개의 댓글