Machineboy空

Excercism - Hyper-optimized Telemetry 정수형 본문

Computer/Coding Test

Excercism - Hyper-optimized Telemetry 정수형

안녕도라 2025. 2. 11. 12:23

문제요약

정수가 입력되면 규칙에 맞게 바이트로 변환해 출력하라.

 

 

https://exercism.org/tracks/csharp/exercises/hyper-optimized-telemetry

 

Hyper-optimized Telemetry in C# on Exercism

Can you solve Hyper-optimized Telemetry in C#? Improve your C# skills with support from our world-class team of mentors.

exercism.org


난이도

Learning Excercise


풀이 포인트

  • 정수 타입 이해 및 문제 이해

16진수 표기란 표현은 잘못된 것.byte표기


REVIEW

 

우선은 문제 이해가 안 가서 여러번 덮어 두었던 문제다.

핵심은 입력된 데이터 크기에 맞는 정수형을 잘 선택하고, 바이트로 변환하면 된다.

 

바이트 표기도 16진법? 이걸 내가 구현해야하는 것으로 이해해 포기했었다.

  • 입력된 데이터 크기에 맞는 정수형을 선택한다.
  • 규칙에 맞게 prefix byte 계산을 한다.
  • 입력된 수를 BitConverter로 바이트로 변환한다.

항상 모범 풀이를 보고서 단계를 쪼개며 분석해보는데,

찬찬히 쪼개어 정답을 맞춘 다음 풀이를 보는 인내심 있는 습관을 기르자..


CODE

using System;

public static class TelemetryBuffer
{
    public static byte[] ToBuffer(long reading)
    {
        byte[] allBytes = new byte[9];

        byte[] bytes;
        if (reading > UInt32.MaxValue || reading < Int32.MinValue)
        {
            allBytes[0] = 0xf8; //248 long
            bytes = BitConverter.GetBytes(reading);
            bytes.CopyTo(allBytes, 1);
        }
        else if (reading > Int32.MaxValue)
        {
            allBytes[0] = 0x4; //4 uint, 256-252
            bytes = BitConverter.GetBytes((uint)reading);
            bytes.CopyTo(allBytes, 1);
        }
        else if (reading > UInt16.MaxValue || reading < Int16.MinValue)
        {
            allBytes[0] = 0xfc; //252
            bytes = BitConverter.GetBytes((int)reading);
            bytes.CopyTo(allBytes, 1);
        }
        else if (reading >= 0)
        {
            allBytes[0] = 0x2; //2
            bytes = BitConverter.GetBytes((ushort)reading);
            bytes.CopyTo(allBytes, 1);
        }
        else
        {
            allBytes[0] = 0xfe; //254
            bytes = BitConverter.GetBytes((short)reading);
            bytes.CopyTo(allBytes, 1);
        }

        return allBytes;
    }

    public static long FromBuffer(byte[] buffer)
    {
        switch ((sbyte)buffer[0])
        {
            case -8:
                return BitConverter.ToInt64(buffer, 1);
            case 4:
                return BitConverter.ToUInt32(buffer, 1);
            case -4:
                return BitConverter.ToInt32(buffer, 1);
            case 2:
                return BitConverter.ToUInt16(buffer, 1);
            case -2:
                return BitConverter.ToInt16(buffer, 1);
            default:
                return 0;
        }
    }
}
using System;
using System.Linq;

public static class TelemetryBuffer
{
    public static byte[] ToBuffer(long reading)
    {
        var bytes = reading switch
        {
            < Int32.MinValue => BitConverter.GetBytes((long)reading).Prepend((byte)(256 - 8)),
            < Int16.MinValue => BitConverter.GetBytes((int)reading).Prepend((byte)(256 - 4)),
            < UInt16.MinValue => BitConverter.GetBytes((short)reading).Prepend((byte)(256 - 2)),
            <= UInt16.MaxValue => BitConverter.GetBytes((ushort)reading).Prepend((byte)2),
            <= Int32.MaxValue => BitConverter.GetBytes((int)reading).Prepend((byte)(256 - 4)),
            <= UInt32.MaxValue => BitConverter.GetBytes((uint)reading).Prepend((byte)4),
            _ => BitConverter.GetBytes((long)reading).Prepend((byte)(256 - 8)),
        };

        return bytes.Concat(new byte[9 - bytes.Count()]).ToArray();
    }

    public static long FromBuffer(byte[] buffer) => buffer[0] switch
    {
        256 - 8 or 4 or 2 => BitConverter.ToInt64(buffer, 1),
        256 - 4 => BitConverter.ToInt32(buffer, 1),
        256 - 2 => BitConverter.ToInt16(buffer, 1),
        _ => 0,
    };
}